home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / science / normix21.zip / NORMIX21 / PCNORMIX.FOR < prev    next >
Text File  |  1995-01-11  |  75KB  |  2,393 lines

  1. c     PC-NORMIX Version 2.1 (January 1995) 
  2. c     Copyright (c) 1995 by John H. Wolfe. All rights reserved.
  3. c     This is a revision of Version 1.1 of PCNORMIX for the
  4. c     286 and above. It runs on 386 and 486 pcs, compiled with Microsoft
  5. c     Fortran Power-Station, unix machines with the f77 compiler, 
  6. c     and the IBM-4381 mainframe with the FORTVS compiler.
  7. c     Only the I/O differs from the 1978 IBM Mainframe version. The 
  8. c     computational algorithms remain unchanged. This version of the program
  9. c     is copyrighted, unlike Version 1.1, which is in the public domain.
  10. c     It may be freely redistributed in its entirety provided that this
  11. c     copyright notice is not removed. It may not be sold for profit or
  12. c     incorporated in commercial programs without the written permission
  13. c     of the copyright holder. Permission is expressly granted for this
  14. c     program to be made available for file transfer from installations
  15. c     offering unrestricted anonymous file transfer on the Internet.
  16. c     This program is provided without any express or implied warranty.
  17. c     The user may modify or recompile the program for his/her own use on any
  18. c     one computer, provided that he/she becomes a Registered user. Distribution
  19. c     of modified or recompiled versions of this program is strictly forbidden
  20. c     without written permission from the copyright holder.
  21. c
  22. c     This (main) program dimensions the arrays.
  23.       implicit real*8 (a-h,o-z)
  24.       real*8 likly
  25.       character*60 fmt
  26.       character*40 nform,dblank
  27.       logical normap
  28. c     external normex
  29.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  30.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  31.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  32.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  33.      3,method,incase,ntyp(20)
  34. c
  35. c*********************************************************************
  36. c  VAX-UNIX or IBM Mainframe VMS version: Remove C from Column 1
  37. c  on next two lines:
  38. c      dimension a(56000)
  39. c      data nadim/56000/
  40. c     These dimensions are currently set to fit into 571K byte RAM with
  41. c     123K of program and 56K 8-byte words.
  42. c  End of Mainframe statement.
  43. c*********************************************************************
  44. c
  45. c*********************************************************************
  46. c  The next statement works only for MS-Fortran on a PC:
  47. c      dimension a[allocatable,huge](:)
  48. c  The next statement works only for MS-Fortran PowerStation on a PC:
  49.        dimension a[allocatable](:)
  50. c  End of MS-Fortran PC statement.
  51. c*********************************************************************
  52. c
  53. c
  54. c    Logical I/O unit numbers are assigned to files as follows:
  55. c    15      Input-form  statements (filename specified interactively,
  56. c                                    default: "thisjob")
  57. c    11      Input data (filename specified on input-form; if blank,
  58. c                       data are read from unit 15 following the format
  59. c                       statement on the input-form)
  60. c    12      Printout of the analysis (filename specified on input-form,
  61. c                                      default: "prinout")
  62. c     3      "kc3temp" Scratch unit containing factor scores
  63. c     9      "kv9temp" Scratch unit containing raw data
  64. c     4      "discrim" = the discriminant scores
  65. c     7      "dumpout"  the parameter estimates if iteration limit is
  66. c                       reached. These can be used to continue the
  67. c                       analysis by including them as initial estimates
  68. c                       on a new input-form.
  69.  
  70.       write(*,10)
  71.    10 format(' Enter the file name for the input-form statements (defaul
  72.      1t = "thisjob")')
  73.       read(*,'(a40)',end=20,err=20)nform
  74.       nform = dblank(nform)
  75.       if(nform .eq. ' ')nform='thisjob'
  76.       go to 30
  77.    20 nform = 'thisjob'
  78.    30 open( 15,file=nform)
  79.       write(*,*)' '
  80.       write(*,*)' Reading input form control statements from'
  81.       write(*,*)'          ',nform
  82.       call inform
  83. c
  84. c     calculate number of bytes occupied by each array
  85.       nb=max0(maxav*4,nvbles*8,168)
  86.       nb=((nb+7)/8)*8
  87.       nc=maxtyp*8
  88. c
  89.       nx=nvbles*nsampl*4
  90.       nx=max0(nx,24000,maxav*(maxav+1)*2 )
  91.       nx=((nx+7)/8)*8
  92. c
  93.       nvc=nvbles*nc
  94.       nv=nvbles*8
  95.       np=max0(nsemi*8,nparam*nc)
  96.       if(normap) then
  97.          ncov=nsemi*24
  98.          nvt=nvbles*nv
  99.          nr=nv
  100.          nvv=nvc
  101.       else
  102.          ncov=nsemi*nc
  103.          nvt=8
  104.          nr=8
  105.          nvv=nv
  106.       endif
  107.       kor=2*(nc+nvc+nvt)+ncov+np+nvv+nvbles*nv+(12+nvbles)*nb+ 24
  108.      1 +nsampl*4 + nsampl*24
  109.       kore=kor + nx + 123000
  110.       kor=kor/8 + 1
  111.       korx = nx/8 + 1
  112.       kor = kor + korx
  113. c*********************************************************************
  114. c  The following two statements work only with MS Fortran on a PC.
  115. c  Remove them for the mainframe or unix versions.
  116.       nadim = kor
  117.       allocate (a(kor))
  118. c  End of MS-Fortran PC statements.
  119. c*********************************************************************
  120.       write(*,200) kore,kor,nadim
  121.   200 format(' Storage requirement=',i8,' decimal bytes',/
  122.      1 ' Required:       DIMENSION A( ',i6,')',/
  123.      2 ' This Program:   DIMENSION A( ',i6,')')
  124.       if(kor .gt. nadim)  then
  125.          write(*,*) ' This problem is too large. Execution terminated.'
  126.          stop
  127.       endif
  128.       vbles=nvbles
  129. c     estimate how long this run will take.
  130.       etime=dble(maxav)*(2.865d0*en*vbles+4.961d0*dble(maxav))
  131.       do 40 l=1,maxt
  132.       t=ntyp(l)+1
  133.       iters=min0(iterx,   (10+nvbles/2)*( ntyp(l)-1)+2 )
  134.       ters=iters
  135.       if(normap) then
  136.       etime=etime+16667.d0*dmax1(0.d0,t+t-7.d0)+1.23d0*en*ters*t*
  137.      1(vbles+2.d0)+4.25d0*t*vbles**2+2.12d0*t*vbles**3+67.d0*t*en
  138.       else
  139.       etime=etime+0.62d0*ters*en*t*( vbles+2.0d0)*(vbles+1.d0)+4.25d0*t*
  140.      1vbles**2 +67.d0*en*t
  141.       endif
  142.    40 continue
  143.       etime=etime/25.0d+6
  144.       n1=1
  145.       n2=n1+nc/8
  146.       n3=n2+nvc/8
  147.       n4=n3+ncov/8
  148.       n5=n4+np/8
  149.       n6=n5+nc/8
  150.       n7=n6+nvc/8
  151.       n8=n7+nvv/8
  152.       n9=n8+nvbles**2
  153.       n10=n9+nvt/8
  154.       n11=n10+nvt/8
  155.       n12=n11+nb/8
  156.       n13=n12+nb/8
  157.       n14=n13+nb/8
  158.       n15=n14+nb/8
  159.       n16=n15+(maxav*nvbles+1)/2
  160.       n17=n16+(maxav+1)/2
  161.       n18=n17+nb/8
  162.       n19=n18+nx/8
  163.       n20 = n19 + (nsampl+1)/2
  164.       write (*,300)etime
  165.   300 format(//' Anticipated execution time (on 486/33DX) =',f8.2,
  166.      1' minutes' )
  167. c
  168.       call normex(a,a(n2),a(n3),a(n4),a(n5),a(n6),a(n7),a(n8),a(n9)
  169.      1,a(n10),a(n11),a(n12),a(n13),a(n14),a(n15),a(n16),a(n17),a(n18)
  170.      2,a(n19),a(n20)  )
  171. c
  172.       kc = 3
  173.       close(kc,status='DELETE')
  174.       close(kv,status='DELETE')
  175.       write(*,*)' Analysis completed.'
  176.       stop
  177. c
  178.       end
  179.       subroutine inform
  180. c     This subroutine reads the input form cards on which the user
  181. c     specifies the options controlling the program.
  182.       implicit real*8 (a-h,o-z)
  183.       real*8 likly
  184.       character*60 fmt
  185.       character*40 infile,lsting,dblank
  186.       logical normap
  187.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  188.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  189.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  190.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  191.      3,method,incase,ntyp(20)
  192.       kpun=7
  193.       maxt=0
  194.       read ( 15, 6) title
  195. 6     format ( 9a8)
  196.       read ( 15, 7)nvbles,nsampl,(ntyp(l),l=1,14),nor,enmin,
  197.      1 htest,maxav,mxhier,iterx,iprint,infile,lsting,fmt
  198.   7     format(t21,i2,t37,i4,t65,/t29,14(1x,i2)/t42,i1,t66,f3.0/
  199.      1  t68,f4.3/t34,i3,t65,i3/t20,i3,t42,i1/t22,a40/t20,a40/t13,a60)
  200.       incase = ialong(fmt)
  201.       ltime=600
  202.       if(htest .eq. 0.0d0) htest=0.999d0
  203.       normap=(nor.ne.1)
  204.       if(enmin.eq. 0.0d0) enmin=nvbles+1
  205.       if (iterx.eq.0) iterx=300
  206.       do 2 i=1,14
  207.       if (ntyp(i).ne.0) go to 2
  208.       do 1 j=i,14
  209.       if (ntyp(j).eq.0) go to 1
  210.       ntyp(i)=ntyp(j)
  211.       ntyp(j)=0
  212.       go to 2
  213. 1     continue
  214.       maxt=i-1
  215.       go to 3
  216. 2     continue
  217.       maxt=14
  218. 3     if (maxt.ne.0) go to 5
  219.       maxt=20
  220.       do 4 i=1,20
  221. 4     ntyp(i)=i
  222. 5     maxtyp=ntyp(maxt)+1
  223.       nsemi=nvbles*(nvbles+1)/2
  224.       nparam=(nvbles+1)*(nvbles+2)/2
  225.       if(normap) nparam=nvbles+1
  226.       en=nsampl
  227.       if(maxav.eq.0) maxav=2000
  228.       maxav=min0(maxav,nsampl)
  229.       ivalue=-1
  230.       infile = dblank(infile)
  231.       if(infile .eq. ' ') then
  232.          inp = 15
  233.       else
  234.          inp = 11
  235.          open( 11,file=infile)
  236.       endif
  237.       lsting = dblank(lsting)
  238.       if(lsting .eq. ' ') lsting = 'prinout'
  239.       call openit(12,lsting)
  240.       write(*,*)' Data will be read on unit#',inp,' from'
  241.       write(*,*)'          ',infile
  242.       write(*,*)' The printout of the analysis will appear on'
  243.       write(*,*)'          ',lsting
  244.       return
  245.       end
  246. c
  247.       function ialong(fmt)
  248. c     Returns ialong = length of the first A format variable specified
  249. c     in the variable format fmt. If ialong = 0, no a-format was found.
  250. c     If ialong = -1, the length of the A format was unspecified.
  251.       character fmt*60,aind*3
  252.       i1 = index(fmt ,'a')
  253.       if(i1 .eq. 0) i1 = index(fmt,'A')
  254.       if(i1 .ne. 0) then
  255.          i2 = index(fmt(i1:i1+3),',')
  256.          leng = i2 - 2
  257.          if (leng .le. 0) then
  258.             print *, 'No length specified for A format'
  259.             ialong = -1
  260.             return
  261.          endif
  262.          aind = fmt(i1+1: i1+leng)
  263.          read(unit=aind,fmt='(i2)')ialong
  264.       else
  265.          ialong = 0
  266.       endif
  267.       return
  268.       end
  269. c     
  270.         
  271.       function dblank(ch)
  272. c     Strip off leading blanks from a character string.
  273.       character*40 ch,dblank,db
  274.       character*1 one(40)
  275.       equivalence (db,one)
  276.       db = ch
  277.       len = 40
  278.       do 10 i=1,len
  279.       if(one(i) .eq. ' ') goto 10
  280.          nb = i - 1
  281.          go to 20
  282.    10 continue
  283.    20 if(nb .eq. 0) go to 50
  284.       do 30 i = 1,len-nb
  285.    30 one(i) = one(i+nb)
  286.       do 40 i = len-nb+1,len
  287.    40 one(i) = ' '
  288.    50 dblank = db
  289.       return
  290.       end
  291.       subroutine normex(lambda,mean,covin,mu,olam,omean,v,t,w,bmat,r,s
  292.      1,b,g,av,dense,member,x,kpath,case)
  293.       implicit real*8 (a-h,o-z)
  294.       real*8 lambda,mean,mu,likly,lnlike(20)
  295.       real*4 x,dense,av
  296.       character*60 fmt
  297.       character*40 fname
  298.       logical normap
  299.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  300.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  301.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  302.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  303.      3,method,incase,ntyp(20)
  304.       dimension lambda(1), mean(1), covin(1),r(1), s(1), b(1),ndf(20),
  305.      1g(1), mu(1), av(1), olam(1), omean(1), dense(1), x(nvbles,nsampl)
  306.      2,v(1),t(1),w(1),bmat(1),member(1),kpath(2),chi(20),pchi(20)
  307.       logical*1 case(24,nsampl)
  308. c
  309. c     This is the controlling program which calls the other subroutines.
  310. c
  311. c     Notice that, as presently programmed, all data must be in core and
  312. c     stored in the array x. It would be relatively easy to reprogram to
  313. c     handle much larger problems by reading x one record at a time from
  314. c     disk each time initle, histog, moment, and assign are called. One
  315. c     should be careful about this, since x is used as a working storage
  316. c     area in kmean and prplot. Also, this method will slow the program
  317. c     by about 20 percent.
  318. c
  319.       convrg=1.0d-4
  320.       kscrat=4
  321.       fname = 'discrim'
  322.       call openit(kscrat,fname)
  323.       rewind kscrat
  324.       call itime (itma)
  325. c     itime is a routine which returns the clock value in 100-ths of a
  326. c     second.
  327. c     ltime is the time limit in minutes.
  328.       itma=6000*ltime+itma
  329.       write(*,*)' Reading the data'
  330.       call initle (lambda,mean,covin,x,case)
  331.       write(*,*)' Entering HISTOG hierarchical clustering'
  332.       call histog(mean,av,dense,x,r,s,g,b,mu,covin,t,member,kpath,case)
  333.       call itime(itmb)
  334.       tmb=itmb/100.0
  335. c     write (12,15)tmb
  336.       do 8 l=1,maxt
  337.       ltye=l
  338.       iter=0
  339.       method=10 +nvbles
  340.       ntypes=ntyp(l)+1
  341.       write(*,*)' Start REVALU to use new initial estimates'
  342.             call revalu (lambda,mean,covin,av,dense,member,r,s)
  343.       call output (lambda,mean,covin,r,s)
  344.       oldlik=-1.0d08
  345.       call tytle
  346.       ldiv=0
  347.       call itime(itme)
  348.       do 5 iter=1,iterx
  349. c     write(*,*)' Start iteration',iter
  350.             call aitken (lambda,mean,covin,x,r,s,b,v,g,mu,olam,omean)
  351. c      write(*,*)'finish aitken'
  352.       elik=likly-oldlik
  353.       dlik=dabs(elik)
  354.       if (elik.gt.-1.0d-5) go to 1
  355.       ldiv=ldiv+1
  356.       if (ldiv.lt.9) go to 2
  357. c     If the likelihood fails 9 times to exceed the maximum likelihood
  358. c     of prior iterations, terminate job.
  359.       write (12,10)
  360.       if (dlik.gt.convrg) itmc=10
  361.       go to 7
  362. 1     oldlik=likly
  363.       ldiv=0
  364.       write (*,11) iter,ntyp(l),likly
  365. c     Test whether the convergence criterion is met.
  366.       if (dlik-convrg) 7,7,2
  367. 2     if (iprint.eq.0) go to 3
  368.       call output (lambda,mean,covin,r,s)
  369.       go to 4
  370. 3     write (12,11) iter,ntyp(l),likly
  371. 4     call itime (itmb)
  372.       itmc=itmb-itma
  373.       tmc=itmc/6000. +ltime
  374. c     Stop and dump current parameter estimates if time limit reached.
  375. c     if (itmc.lt.0) go to 5
  376. c     write (12,13) tmc
  377. c     go to 6
  378. 5     continue
  379.       go to 7
  380. 6     call dumper (lambda,mean,covin,r,s)
  381. 7     call itime(itmb)
  382. c     tme=(itmb-itme)/100.0
  383. c     tmr=tmc*60.0
  384. c     write (12,14)tme,tmr
  385.       call output (lambda,mean,covin,r,s)
  386.       if(ntypes.eq.2) go to 20
  387.       nrank=min0(ntypes-2,nvbles,8)
  388.       write(*,*)' Start ASSIGN'
  389.       call assign(lambda,mean,covin,x,r,s,b,v,g,mu,t,w,bmat,case)
  390.       if(normap) then
  391.                  call mapper(x,r,s)
  392.                  write(*,*)' Finish MAPPER plot of discriminant scores'
  393.       endif
  394.       rewind kv
  395.       read(kv) ((x(i,k),i=1,nvbles),k=1,nsampl)
  396. c     if (itmc.ge.0) go to 9
  397. c     Test whether likelihood is significantly greater for more types.
  398. 20    ratio=likly-prelik
  399.       prelik=likly
  400.       ntypes=ntyp(l)
  401.       lnlike(l) = likly      
  402.       if (l.le.1) go to 8            
  403.       ntyold=ntyp(l-1)
  404.       ndegre=(nparam-1)*(ntypes-ntyold)*2
  405.       chisq=2.0*ratio*(en-0.5-nvbles-ntypes/2.0)/en
  406.       pchisq=chisqp(chisq,ndegre)
  407.       ndf(l) = ndegre
  408.       chi(l) = chisq
  409.       pchi(l) = pchisq
  410.       call tytle
  411.       write (12,12) ntypes,ntyold,ratio,ndegre,chisq,pchisq
  412.       if ((htest .lt. 0.998d0) .and. (pchisq .gt. htest)) go to 9
  413. 8     continue
  414. 9     if(normap) end file kscrat
  415.       call tytle
  416.       write(12,16)
  417.       write(12,17) ntyp(1),lnlike(1)
  418.       if(maxt .gt. 1) then
  419.       do 90 l=2,maxt
  420.          write(12,17) ntyp(l),lnlike(l),chi(l),ndf(l),pchi(l)
  421.    90 continue
  422.       endif   
  423.       return
  424. c
  425. c
  426. 10    format (/,5x,'Job terminated--iterations are not converging')
  427. 11    format (' Iteration',i4, 3x,'Log likelihood of',i3,' types in this
  428.      1 sample =',g20.8)
  429. 12    format (' Logarithm of likelihood ratio of',i3,' to',i3,' types=',
  430.      1 e18.8,/,' Pseudo Chi-square with',i3,' degrees of freedom=',f10.2
  431.      2,/,' "Probability" of null hypothesis=',f11.8)
  432. c 13  format (39h Time limit exceeded. Computation time=f6.2,8h minutes)
  433. c 14  format(//40x,'Iteration time =',f12.2,' seconds.'/40x,'Total time
  434. c    1used =',f11.2,' seconds.')
  435. c 15  format(//40x,'Time in hierarchical grouping =',f8.2,' seconds.')
  436.    16 format(/'         Summary of Likelihood Statistics ',/
  437.      * '  Types    Log Likelihood  Chi-square  DF  "Probability"')
  438.    17 format(i5,g20.8,f12.2,i4,f14.4)
  439.       end
  440.       subroutine openit(no,fname)
  441.       character*40 fname
  442.       logical isther
  443.       inquire(file=fname,exist=isther)
  444.       if(isther) then
  445.       open(no,file=fname,status='OLD')
  446.       else
  447.       open(no,file=fname,status='NEW')
  448.       endif
  449.       return
  450.       end
  451.       subroutine openun(no,fname)
  452.       character*40 fname
  453.       logical isther
  454.       inquire(file=fname,exist=isther)
  455.       if(isther) then
  456.       open(no,file=fname,status='OLD',form='UNFORMATTED')
  457.       else
  458.       open(no,file=fname,status='NEW',form='UNFORMATTED')
  459.       endif
  460.       return
  461.       end
  462.       subroutine initle (lambda,mean,covin,x,case)
  463.       implicit real*8 (a-h,o-z)
  464.       real*8 lambda,mean,likly
  465.       real*4 x
  466.       character*60 fmt*60,acase*24
  467.       logical normap
  468.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  469.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  470.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  471.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  472.      3,method,incase,ntyp(20)
  473.       dimension lambda(1),mean(nvbles,2),covin(nsemi,2),
  474.      1 x(nvbles,1)
  475.       logical*1 case(24,nsampl),lcase(24)
  476.       equivalence (acase,lcase)
  477.       ntypes=0
  478.       iter=0
  479.       likly=0.0
  480.       do 1 l=1,maxtyp
  481.       lambda(l)=0.0
  482.       do 1 i=1,nvbles
  483. 1     mean(i,l)=0.
  484.       naxtyp=maxtyp
  485.       if(normap) naxtyp=3
  486.       do 12 l=1,naxtyp
  487.       do 12 ij=1,nsemi
  488. 12    covin(ij,l)=0.0d0
  489. 3     do 4 j=1,nsampl
  490. c     Read in all the data.
  491.       if(incase .eq. 0) then
  492.          read (inp,fmt) (x(i,j),i=1,nvbles)
  493.       else
  494.          read (inp,fmt) acase,(x(i,j),i=1,nvbles) 
  495. c        write(12,fmt) acase,(x(i,j),i=1,nvbles)
  496.          do 41 i=1,incase
  497.   41     case(i,j) = lcase(i)
  498.       endif
  499. 4     continue
  500.       do 5 k=1,nsampl
  501. c     Calculate the overall means and covariances for the whole sample.
  502.       ij=0
  503.       do 5 i=1,nvbles
  504.       mean(i,1)=mean(i,1)+x(i,k)
  505.       do 5 j=i,nvbles
  506.       ij=ij+1
  507. 5     covin(ij,1)=covin(ij,1)+x(i,k)*x(j,k)
  508.       ij=0
  509.       do 7 i=1,nvbles
  510.       do 6 j=i,nvbles
  511.       ij=ij+1
  512. 6     covin(ij,1)=(covin(ij,1)*en-mean(i,1)*mean(j,1))/(en*en)
  513. 7     mean(i,1)=mean(i,1)/en
  514.       return
  515. c
  516. c
  517. 8     format (f8.4)
  518. 9     format (10f8.4)
  519.       end
  520.       subroutine histog(mean,av,dense,x,r,s,g,b,mu,covin,t,member,kpath,
  521.      * case)
  522. c     The clusters which are formed are used later in the program for
  523. c     initial estimates of the parameters.
  524.       implicit real*8 (a-h,o-z)
  525.       real*8 mean,mu,likly
  526.       real*4 x,dense,r,s,av
  527.       character*60 fmt
  528.       character*40 fname
  529.       logical normap,kmax,grprin
  530.       integer b,g
  531.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  532.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  533.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  534.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  535.      3,method,incase,ntyp(20)
  536.       logical*1 case(24,nsampl)
  537.       dimension mean(nvbles,maxtyp),x(nvbles,nsampl),av(nvbles,maxtyp),
  538.      1 dense(maxtyp),r(nvbles),g(1),mu(1),covin(nsemi,1),s(1)
  539.      2,member(1),b(1),t(nvbles,nvbles),kpath(1)
  540.       do 2 i=1,nsemi
  541. 2     mu(i)=covin(i,1)
  542.       kv=9
  543.       kc=3
  544.       fname = 'kv9temp'
  545.       call openun(kv,fname)
  546.       fname = 'kc3temp'
  547.       call openun(kc,fname)
  548.       do 50 ngrp = 1,3
  549. c     Repeat the hierarchical grouping three times.
  550.       rewind kv
  551.       rewind kc
  552.       write(*,*)'       Factoring the variables'
  553.       call uplow(mu,nvbles,-1)
  554.       call eigen(mu,t,nvbles,0)
  555.       write(kv) ((x(i,k),i=1,nvbles),k=1,nsampl)
  556.       ii=0
  557.       do 4 i=1,nvbles
  558.       ii=ii+i
  559.       ra=1.0d0/dsqrt(mu(ii))
  560.       do 3 j=1,nvbles
  561. 3     t(j,i)=t(j,i)*ra
  562. 4     continue
  563.       do 21 k=1,nsampl
  564.       do 20 i=1,nvbles
  565.       r(i)=0.0
  566.       do 20 j=1,nvbles
  567. 20    r(i)=r(i)+t(j,i)*(x(j,k)-mean(j,1))
  568. c     write(kc) r
  569.       write(kc) (r(ir),ir=1,nvbles)
  570.    21 continue
  571.       write(*,*)'       Ward hierarchical grouping'
  572.       maxhi = mxhier
  573.       if(mxhier .eq. 0) maxhi=30
  574.       maxhi = min0(maxav,maxhi)
  575.       grprin = ((mxhier .ne. 0) .or. (ngrp .eq. 3))
  576.       if(grprin) call tytle 
  577.       call kmean(av,dense,x,s,member,b,g,kpath,maxav,maxhi,nsampl,
  578.      1 nvbles,kc,incase,case,grprin)
  579.       write(*,*)'       Compute means of merged clusters'
  580.       rewind kv
  581.       read(kv) ((x(i,k),i=1,nvbles),k=1,nsampl)
  582.       do 24 l=1,maxav
  583.       do 24 i=1,nvbles
  584. 24    av(i,l)=0.0
  585.       l=0
  586.       do 28 k=1,nsampl
  587.       ki=kpath(k)
  588.       if(ki .le. 0) then
  589.          ki=-ki
  590.          l=l+1
  591.       endif
  592.       do 28 i=1,nvbles
  593. 28    av(i,l)=av(i,l)+x(i,ki)
  594.  
  595.       ltypes=min0(10,maxav)
  596.       d=0.0
  597.       ij=0
  598.       do 51 i=1,nvbles
  599.       r(i)=0.0
  600.       do 51 j=i,nvbles
  601.       ij=ij+1
  602.    51 mu(ij)=covin(ij,1)+mean(i,1)*mean(j,1)
  603.       kmax=.false.
  604.       do 57 k=1,maxav
  605.       if(member(k) .ge.ltypes) go to 55
  606.       if(d.le. 0.5) go to 55
  607.    58 ij=0
  608.       do 53 i=1,nvbles
  609.       do 53 j=i,nvbles
  610.       ij=ij+1
  611.    53 mu(ij)=mu(ij)-r(i)*r(j)/(d*en)
  612.       if(kmax) go to 50
  613.       d=0.0
  614.       do 54 i=1,nvbles
  615.    54 r(i)=0.0
  616.    55 d=d+dense(k)
  617.       do 56 i=1,nvbles
  618.    56 r(i)=r(i)+av(i,k)
  619.       kmax=k.eq.maxav
  620.       if(kmax) go to 58
  621.    57 continue
  622.    50 continue
  623.  
  624.       do 40 l=1,maxav
  625.       do 40 i=1,nvbles
  626.    40 av(i,l)=av(i,l)/dense(l)
  627. c      if mxhier = 0, no printout occurs of means at each stage of the
  628. c      hierarchical grouping. Elsewhere in the program, mxhier defaults
  629. c      to 30, but if you want this printout here, you must enter a
  630. c      positive integer explicitly for mxhier on the input form.
  631.       if(mxhier .eq. 0) return
  632.       call tytle
  633.       write (12,1140)
  634.       last=0
  635.       do 440 i=1,maxav
  636.          k=last+1
  637.          l=dense(i)
  638.          last=l+k-1
  639.          write (12,1130)i,l
  640.          write (12,1135)(kpath(j),j=k,last)
  641. 440   write (12,1150)(av(j,i),j=1,nvbles)
  642.       do 35 mtypes=2,maxav
  643.          ltypes=maxav-mtypes+2
  644.          last=g(ltypes)
  645.          j=last
  646.          jind=1
  647.          do 29 i=1,nvbles
  648. 29       r(i)=av(i,j)*dense(j)
  649.          awt=dense(j)
  650. 30       j=j+jind
  651.          if(j.gt.maxav) go to 32
  652.          if(member(j).lt.ltypes*jind) go to 32
  653.          do 31 i=1,nvbles
  654. 31       r(i)=r(i)+av(i,j)*dense(j)
  655.          awt=awt+dense(j)
  656.          if(member(j).ge.ltypes) go to 30
  657. 32       if(j.lt.last) go to 33
  658.          j=last
  659.          jind=-1
  660.          go to 30
  661. 33       do 34 i=1,nvbles
  662. 34       r(i)=r(i)/awt
  663.          write (12,1160)last,j
  664.          nj=awt
  665.          nj1=b(j)
  666.          nj2=nj1+nj-1
  667.          write (12,1130)j,nj
  668.          write (12,1135)(kpath(m),m=nj1,nj2)
  669. 35    write (12,1150)(r(i),i=1,nvbles)
  670. 1130  format(/30x,'Cluster',i4,10x,i4,' points')
  671. 1135  format(20i4)
  672. 1140  format(42x,'Kmeans analysis'//)
  673. 1150  format(10f12.4)
  674. 1160  format(/20x,'Merging cluster',i4,' with cluster',i4,
  675.      1' results in the revised' )
  676.       return      
  677. c      
  678.       end
  679.       subroutine kmean(av,wt,a,best,member,kgrp,lgrp,kpath,n,mxhier,
  680.      1 ns,nv,nti,incase,case,grprin)
  681. c     Adapted from ward's hierarchical grouping program
  682. c     by John H. Wolfe                 
  683. c
  684. c     This routine combines MacQueen's Kmeans clustering procedure with
  685. c     Ward's hierarchical grouping.
  686. c            ***references***
  687. c     MacQueen,J.   Fifth Berkeley Symposium(1965)
  688. c     Ward,J.  PERSUB Reference Manual(PRL-TR-67-3) (1967)
  689. c     Definitions:
  690. c        n = maximum number of groups
  691. c        ns= number of points to be grouped.
  692. c        nv= number of variables.
  693. c        nti=logical unit containing data to be clustered.
  694. c        wt(i)=number of points in cluster i.
  695. c        av(j,i)=mean of variables j in cluster i.
  696. c        a =  n*(n+1)/2 words of working storage used by the program
  697. c
  698. c         On return from this routine, kpath will be a list of points.
  699. c     kpath(i) will be negative for the first member of one of the n
  700. c     groups and kpath(i+1),kpath(i+2), etc., will have the remaining
  701. c     members in that group.  member(j) will be the number of groups
  702. c     left after the j-th group is merged with another group.
  703. c
  704. c     This routine expects that logical unit nti contains the data to
  705. c     be clustered.  The data should have been properly scaled or
  706. c     converted to factor scores  and written as unformatted (binary)
  707. c     records
  708. c
  709.       logical*1 case(24,ns)
  710.       logical grprin
  711.       dimension a( 1),kgrp(n),kpath(ns),wt(n),member(n),best(n),av(nv,n)
  712.      1,lgrp(n)
  713. c
  714. c     The program first performs a kmeans analysis and then
  715. c     hierarchically groups the groups.
  716. c  1. Initially, each of the first n data points is a separate cluster.
  717. c  2. The inter-group distances, a, are computed.
  718. c  3. The nearest two groups are combined.
  719. c  4. A new data point is read into the space left by the merger.
  720. c  5. The distances of all the clusters to this new point are computed.
  721. c  6. Go back to step 3 until all the data has been read.
  722. c  7. Hierarchically  group the n groups.
  723. c
  724. c     Initialize
  725.       na = (n * (n+1))/2
  726.       ntwo=n+n
  727.       none=n-1
  728.       if(nti.ne.0) rewind nti
  729.       ks=n
  730.       numg=n
  731.       do 10  i=1,n
  732.       if(nti.ne.0) read (nti) (av(k,i),k=1,nv)
  733. c      write(*,*)i,(av(k,i),k=1,nv)
  734.       lgrp(i)=i
  735.       kgrp(i)=i+1
  736.       best(i)=1.0e35
  737. 10    wt(i)=1.0
  738.       kgrp(n)=0
  739.       do 15 i=1,ns
  740.  15   kpath(i)=0
  741. c     A group is identified by the least index of its members
  742. c     If i is a member of a group, kpath(i) is another member.
  743. c     If i is the beginning of a group, kgrp(i) begins the next group.
  744. c     lgrp(i)= the leading member of group i
  745. c     A diagonal element of a is the within-group dispersion.
  746. c     The value of a in row i,column j is the dispersion which would
  747. c     result from combining groups i and j .
  748. c     Compute di  block 2
  749. c     write(*,*) 'Compute a(ij)'
  750.       ij=0
  751.       do 40 i=1,none
  752.       ij=ij+1
  753.       a(ij)=0.0
  754. c     write(*,*)i,(av(k,i),k=1,nv)
  755.       do 30 j=i,none
  756.       ij=ij+1
  757.       a(ij)=0.0
  758.       do 20 k=1,nv
  759.  20   a(ij)=a(ij)+(av(k,i)-av(k,j+1))**2
  760.       a(ij)=a(ij)/2.0
  761.       dit=a(ij)
  762.       if(dit.ge.best(i)) go to 30
  763.       best(i)=dit
  764.       member(i)=j+1
  765.  30   continue
  766.  40   continue
  767.       a(na)=0.0
  768.  50   i=1
  769.       di=1.0e35
  770.       do 60 j=1,numg
  771.       if(best(i).ge.di) go to 60
  772.       di=best(i)
  773.       ids=i
  774.  60   i=kgrp(i)
  775.  70   jds=member(ids)
  776.       if(jds.gt.ids) go to 100
  777.       ids=jds
  778.       go to 70
  779. c     Update kgrp and kpath  block 3
  780. 100   i=ids
  781.       numg=numg-1
  782.       best(jds)=di
  783. 110   if(kgrp(i)-jds)120,130,120
  784. 120   i=kgrp(i)
  785.       go to 110
  786. 130   kgrp(i)=kgrp(jds)
  787.       kgrp(jds)=-numg
  788.       i=lgrp(ids)
  789. 140   if(kpath(i))150,160,150
  790. 150   i=kpath(i)
  791.       go to 140
  792. 160   kpath(i)=lgrp(jds)
  793. c     Update hyp matrix block 4
  794.       i=1
  795.       best(ids)=1.0e35
  796.       l =((ntwo-ids)*(ids-1))/2+ids
  797.       k =((ntwo-jds)*(jds-1))/2+jds
  798.       m=l+jds-ids
  799.       plop=a(m)
  800.       tsum1=a(m)*(wt(ids)+wt(jds))
  801.       tsum3= (a(l)* wt(ids))+ (a(k)*wt(jds))
  802.       a(l)=plop
  803.       do 350 im=1,numg
  804.       ii=((ntwo-i  )*(i  -1))/2+i
  805.       if(i-ids)210,350,240
  806. 210   m=ii+ids-i
  807.       go to 250
  808. 240   m=l+i-ids
  809. 250   if(i-jds)260,270,270
  810. 260   m1=ii+jds-i
  811.       go to 280
  812. 270   m1=k+i-jds
  813. 280   a(m)=(a(m1)*(wt(i)+wt(jds))+ (
  814.      1a(m)*(wt(i)+wt(ids)))+  (tsum1
  815.      2-tsum3-(a(ii)*wt(i))))/(wt(i)+wt(jds)+wt(ids) )
  816.       dit=a(m)-plop-a(ii)
  817.       if(dit.ge.best(ids)) go to 290
  818.       best(ids)=dit
  819.       member(ids)=i
  820. 290   if(member(i).ne.ids.and.member(i).ne.jds) go to 340
  821.       best(i)=1.0e35
  822.       j=i
  823. 300   j=kgrp(j)
  824.       if(j.le.0) go to 350
  825.       jj=((ntwo-j)*(j-1))/2+j
  826.       ij=ii+j-i
  827.       dot=a(ij)-a(ii)-a(jj)
  828.       if(dot.ge.best(i)) go to 300
  829.       best(i)=dot
  830.       member(i)=j
  831.       go to 300
  832. 340   if(dit.ge.best(i)) go to 350
  833.       best(i)=dit
  834.       member(i)=ids
  835. 350   i=kgrp(i)
  836.       wts=wt(ids)
  837.       wt(ids)=wt(ids)+wt(jds)
  838.       if(ks.eq.ns) go to 359
  839.       ks=ks+1
  840.       numg=n
  841.       lgrp(jds)=ks
  842.       kgrp(jds-1)=jds
  843.       kgrp(jds)=jds+1
  844.       kgrp(n)=0
  845.       do 351 i=1,nv
  846.   351 av(i,ids)=(wts*av(i,ids)+wt(jds)*av(i,jds))/wt(ids)
  847.       read(nti) (av(i,jds),i=1,nv)
  848.       wt(jds)=1.0
  849.       best(jds)=1.0e35
  850.       m=jds
  851.       jadd=n
  852.       jj=1
  853.       do 355 j=1,n
  854.       dit=a(jj)
  855.       if(j.eq.jds) go to 354
  856.       do 352 i=1,nv
  857.   352 dit =dit +(av(i,jds)-av(i,j))**2
  858.       a(m)=dit *wt(j  )/(wt(j  )+1.0)
  859.       dit=a(m)-a(jj)
  860.       if(j.gt. jds) go to 353
  861.       if(dit .ge. best(j)) go to 354
  862.       best(j)=dit
  863.       member(j)=jds
  864.       go to 354
  865. 353   if(dit .ge. best(jds)) go to 354
  866.       best(jds)=j
  867.       member(jds)=j
  868.       best(jds)=dit
  869.  354  jadd=jadd-1
  870.       if(j.ge.jds) jadd=1
  871.       jj=jj+n-j+1
  872.   355 m=m+jadd
  873. 359   if(numg-1) 360,360,50
  874. c     Out put  block 5
  875. 360   la=0
  876.       do 361 i=1,n
  877.       l=lgrp(i)
  878.       if(kpath(l).eq.0) la=i
  879. 361   kpath(l)=-kpath(l)
  880.       call relist(kpath)
  881.       k=0
  882.       do 362 i=2,ns
  883.       if(kpath(i).ge.0) go to 362
  884.       k=k+1
  885.       do 363 l=1,n
  886.       if(lgrp(l).eq. kpath(i-1)) go to 364
  887. 363   continue
  888. 364   member(k)=l
  889.       kpath(i-1)=-kpath(i-1)
  890.       kpath(i)=-kpath(i)
  891.       wt(k)=0.0
  892. 362   wt(k)=wt(k)+1.0
  893.       wt(n)=wt(n)+1.0
  894.       if(la.eq.0) go to 371
  895.       kpath(ns)=-kpath(ns)
  896.       member(n)=la
  897.       wt(n)=1.0
  898.       do 370 k=1,n
  899.       l=member(k)
  900. 366   if(l-k) 367,370,368
  901. 367   l=member(l)
  902.       go to 366
  903. 368   do 369 j=1,nv
  904.       temp=av(j,k)
  905.       av(j,k)=av(j,l)
  906. 369   av(j,l)=temp
  907. 370   continue
  908. 371   do 372 l=1,n
  909.       k=member(l)
  910.       j=-kgrp(k)
  911.       member(l)=j
  912. 372   lgrp(j+1)=l
  913. c     Member(l)= stage of group l
  914. c     lgrp(j)= group whose stage is j-1
  915.       l=0
  916.       do 373 k=1,ns
  917.       if(kpath(k).gt.0) go to 373
  918.       l=l+1
  919.       kgrp(l)=k
  920. 373   continue
  921. c     kgrp(l)= the position in kpath which begins group l
  922.       if(grprin) call hgraph(mxhier,n,ns,kpath,member,incase,case)
  923.       return
  924.       end
  925.       
  926.       subroutine hgraph(mxhier,n,ns,kpath,member,incase,case)
  927.       integer rank,stage 
  928.       character*2 bar,gram     
  929.       character char*1,alph*24,fmt8x*180,fmt9x*60
  930.       logical*1 case(24,ns),lchar
  931.       dimension kpath(ns),member(n)
  932.       dimension gram(80),bar(2)      
  933.       equivalence (char,lchar)
  934.       data bar/' .',' X'/
  935. c     lineln = number of columns displayed on one page
  936.       lineln = 30
  937.       if(incase .gt. 0) then
  938.          m1 = max0(1,(incase+1)/3)
  939.          m2 = incase-m1+2
  940.          write(fmt8x,1010)m1,m2
  941.  1010 format(
  942.      *'(1h ,39x,21hHierarchical Grouping,//60x,16hNumber of Groups,/,
  943.      * 3x,24hRank  Item  Kmeans Stage,',i2,'x,2hID,',i2,'x,i3,i8,5i10)')
  944.  
  945. c      write(12,*)' fmt8x =',fmt8x    
  946.       endif
  947.       
  948.       do 430 lcol=1,mxhier,lineln
  949.          k2=min0(lcol+lineln-1,mxhier)
  950.          linelg = (k2+1-lcol) 
  951.          linelg2 = linelg*2
  952.        if(incase .ne. 0) then            
  953. c           Set up format fmt9x for one line, depending on part of printout                    
  954.             write(fmt9x,1020)incase,linelg
  955.  1020       format('(2i6,2i7,4x,a',i2.2,',2x,',i2,'a2)')
  956. c           write(12,*)' fmt9x =',fmt9x
  957.          endif
  958.          
  959.          kmean=0      
  960.          do 420 rank=1,ns
  961.             if(mod(rank,50) .eq. 1) then
  962.                if(incase .eq. 0) then     
  963.                  write (12,1030)lcol,(j,j=lcol+4,k2,5)
  964.               else       
  965.                  write(12,fmt8x)lcol,(j,j=lcol+4,k2,5)
  966.                endif              
  967.             endif
  968.  1030 format(1h ,39x,'Hierarchical Grouping'//60x,'Number of Groups'/3x
  969.      1,'Rank  Item  Kmeans Stage',5x,i10,i8,5i10)
  970.              
  971.             stage=n+1
  972.             j=kpath(rank)
  973.             if(j.le.0) then
  974.                kmean=kmean+1
  975.                stage=member(kmean)
  976.                j=-j
  977.             endif
  978.             lk=max0(0,stage -lcol+1)+ 1
  979.             if(incase .gt. 0) then
  980. c              Copy case ==> alph
  981.                do 400 ii=1,incase
  982.                   lchar = case(ii,j)
  983.   400          alph(ii:ii) = char
  984.             endif
  985.       
  986.             do 410 k=1,linelg2
  987.                if(k .lt. lk) then
  988.                   gram(k)=bar(2)
  989.                else
  990.                   gram(k)=bar(1)
  991.                endif
  992.   410       continue
  993.  
  994.             if(incase .eq. 0) then
  995.                write (12,1040)rank,kpath(rank),kmean,stage,
  996.      *         (gram(ig),ig=1,linelg)
  997.  1040          format(2i6,2i7,14x,30a2)
  998.             else
  999.                write (12,fmt9x)rank,kpath(rank),kmean,stage,alph,
  1000.      *         (gram(ig),ig=1,linelg)
  1001.             endif
  1002.   420    continue
  1003.   430 continue
  1004.  
  1005.  
  1006.       return
  1007.       end
  1008.       
  1009.       subroutine relist(kpath)
  1010. c
  1011. c     Given a list, kpath, such that kpath(i) is the next element of
  1012. c     the list after i, this routine reorders kpath so that kpath(i) is
  1013. c     the i-th element of the list.
  1014. c
  1015.       dimension kpath(1)
  1016.       l=1
  1017.       j=0
  1018. 1     j=j+1
  1019.       m=iabs(l)
  1020. 2     if(m-j) 3,4,5
  1021. 3     m=iabs(kpath(m))
  1022.       go to 2
  1023. 4     i=kpath(m)
  1024.       go to 6
  1025. 5     i=kpath(m)
  1026.       kpath(m)=kpath(j)
  1027. 6     kpath(j)=l
  1028.       l=i
  1029.       if(i.ne.0) go to 1
  1030.       return
  1031.       end
  1032.  
  1033.       subroutine revalu (lambda,mean,covin,av,dense,member,r,s)
  1034. c     This subroutine re-evaluates previous estimates of the parameters
  1035. c     and finds initial estimates preparatory to iteration. It is called
  1036. c     every time the number of hypothesized types is increased.
  1037. c     Revised 9 Jan 95 to fix a bug reported by B. Robinson in which
  1038. c     only the means of the first cluster were read under the normap option.
  1039.       implicit real*8 (a-h,o-z)
  1040.       real*8 lambda,mean,likly
  1041.       real*4   dense ,av
  1042.       character*60 fmt
  1043.       logical normap
  1044.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1045.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1046.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1047.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1048.      3,method,incase,ntyp(20)
  1049.       dimension lambda(1), mean(nvbles,2), covin(nsemi,2), av(nvbles,2),
  1050.      1 dense(1),member(1),r(nvbles),s(nvbles)
  1051.       ltypes=ntypes-1
  1052.       do 1 l=2,ntypes
  1053.       lambda(l)=0.0d0
  1054.       do 1 i=1,nvbles
  1055. 1     mean(i,l)=0.0d0
  1056.       l=1
  1057.       do 2 k=1,maxav
  1058.       if(member(k).lt.ltypes) l=l+1
  1059.       lambda(l)=lambda(l)+dense(k)
  1060.       do 2 i=1,nvbles
  1061. 2     mean(i,l)=mean(i,l)+av(i,k)*dense(k)
  1062.       do 4 l=2,ntypes
  1063.       do 3 i=1,nvbles
  1064. 3     mean(i,l)=mean(i,l)/lambda(l)
  1065. 4     lambda(l)=lambda(l)/en
  1066.       ij=0
  1067.       do 5 i=1,nvbles
  1068.       do 5 j=i,nvbles
  1069.       ij=ij+1
  1070.       covin(ij,2)=covin(ij,1)+mean(i,1)*mean(j,1)
  1071.       do 5 l=2,ntypes
  1072. 5     covin(ij,2)=covin(ij,2)-lambda(l)*mean(i,l)*mean(j,l)
  1073.       if(.not. normap) then
  1074.          do 6 l=2,ntypes
  1075.          do 6 i=1,nsemi
  1076. 6        covin(i,l)=covin(i,2)
  1077.       endif
  1078.     8 if((ivalue .eq. 0) .or. (ltypes .lt. ivalue)) return
  1079.       if(ltypes .eq. ivalue) go to 10
  1080.       read ( 15, 100)ivalue,imn,istd,icor
  1081.       go to 8
  1082.    10 sump = 0.0d0
  1083.       do 17 l=2,ntypes
  1084.       read ( 15, *)p
  1085.       if(p.ne.0.0d0) lambda(l)=p
  1086.       sump = sump + lambda(l)
  1087.       if(imn.ne.0) read ( 15, *)(mean(i,l),i=1,nvbles)
  1088.       if(normap .and. l .ne. ntypes) go to 17
  1089.       if(istd.ne.0) then
  1090.          read ( 15, *)(s(i),i=1,nvbles)
  1091.          k=0
  1092.          do 15 i=1,nvbles
  1093.          if(icor.eq.0) then
  1094.             do 12 j=1,nvbles
  1095.    12       r(j)=0.0d0
  1096.             r(i)=1.0d0
  1097.          else
  1098.             read ( 15, *)(r(j),j=1,nvbles)
  1099.        endif
  1100.          do 15 j=i,nvbles
  1101.          k=k+1
  1102.    15    covin(k,l)=r(j)*s(j)*s(i)
  1103.       endif
  1104.    17 continue
  1105. c     Standardize lambdas to sum to one.
  1106.       do 18 l=2,ntypes
  1107.    18 lambda(l) = lambda(l)/sump
  1108.       return
  1109.   100 format(25x,i2,16x,i1,10x,i1,14x,i1)
  1110.       end
  1111.  
  1112.       subroutine itime(it)
  1113.       it = 0
  1114.       return
  1115.       end
  1116.  
  1117.       subroutine aitken (lambda,mean,covin,x,r,s,b,v,g,mu,olam,omean)
  1118. c     This subroutine does all the computations of a single iteration
  1119. c     for improved estimates of the parameters.
  1120.       implicit real*8 (a-h,o-z)
  1121.       real*8 lambda,mean,mu,likly
  1122.       real*4 x
  1123.       character*60 fmt
  1124.       logical normap
  1125.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1126.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1127.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1128.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1129.      3,method,incase,ntyp(20)
  1130.       dimension lambda(1),mean(nvbles,2),covin(nsemi,2),mu(nparam,2),
  1131.      1   b(1),olam(1),omean(nvbles,2) ,r(1),s(1),g(1),x(1),v(nvbles,1)
  1132.       xlimit=amin0(40,(iter/5)*10)
  1133. c     When xlimit=0, all points are assigned a membership probability of
  1134. c     1.0 in their nearest cluster.
  1135.       n=nvbles-1
  1136.       luck=1
  1137.       bigest=20.0
  1138.       small=1.0-1.0/bigest
  1139.       lqq=nsemi
  1140.       do 3 l=2,ntypes
  1141.       if(l.gt.2.and.normap) go to 2
  1142.       call syminv (covin,nvbles,detm,r,s,g,lqq)
  1143.       if(normap) go to 2
  1144.       if (enmin.lt.en*lambda(l)) go to 2
  1145.       lsing=l-1
  1146.       nsing=en*lambda(l)
  1147.       oldlik=-1.0d+10
  1148.       write (12,101)lsing,nsing,oldlik
  1149.   101 format(' Type',i3,' with ',i3,' points approaching singularity'/
  1150.      1' Log Likelihood re-initialized to',d15.8)
  1151.       ij=0
  1152.       do 1 i=1,nvbles
  1153.       do 1 j=i,nvbles
  1154.       ij=ij+1
  1155.       covin(ij,l)=covin(ij,1)+mean(i,1)*mean(j,1)
  1156.       do 1 m=2,ntypes
  1157. 1     covin(ij,l)=covin(ij,l)-mu(i+1,m)*mu(j+1,m)/(mu(1,m)*en)
  1158.       call syminv (covin,nvbles,detm,r,s,g,lqq)
  1159. 2       b(l)=dlog(lambda(l))-0.5*detm
  1160. 3     lqq=lqq+nsemi
  1161.       likly=0.0
  1162.       do 4 l=2,ntypes
  1163.       do 4 i=1,nparam
  1164. 4     mu(i,l)=0.0
  1165.       if(normap) go to 40
  1166.       iii=nvbles
  1167.       ii=1
  1168.       do 6 i=1,nvbles
  1169.       do 5 l=2,ntypes
  1170. 5     covin(ii,l)=covin(ii,l)/2.0
  1171.       ii=ii+iii
  1172. 6     iii=iii-1
  1173.       go to 47
  1174. 40    k=1
  1175.       do 42 i=1,nvbles
  1176.       likly=likly-0.5*covin(k,2)*(covin(k,1)+mean(i,1)**2)*en
  1177.       k=k+1
  1178.       if (i.gt.n) go to 42
  1179.       do 41 j=i,n
  1180.       likly=likly-covin(k,2)*(covin(k,1)+mean(j+1,1)*mean(i,1))*en
  1181. 41    k=k+1
  1182. 42    continue
  1183.       do 46 l=2,ntypes
  1184.       do 45 i=1,nvbles
  1185.       k=i
  1186.       n=nvbles
  1187.       v(i,l)=0.0d0
  1188.       if (i.eq.1) go to 44
  1189.       do 43 j=2,i
  1190.       v(i,l)=v(i,l)+covin(k,2)*mean(j-1,l)
  1191.       n=n-1
  1192.       k=n+k
  1193. 43    continue
  1194. 44    do 45 j=i,nvbles
  1195.       v(i,l)=v(i,l)+covin(k,2)*mean(j  ,l)
  1196. 45    k=k+1
  1197.       do 46 i=1,nvbles
  1198. 46    b(l)=b(l)-v(i,l)*mean(i,l)*0.5d0
  1199. c     write(*,*)'Start moment'
  1200. 47          call moment (mean,covin,x,r,s,b,g,mu,v)
  1201. c     write(*,*)'Finish moment'
  1202.       byg=1.0
  1203.       if (method.gt.0) go to 8
  1204.       byg=bigest
  1205.       do 7 l=2,ntypes
  1206.       delta=mu(1,l)/en-lambda(l)
  1207.       biga=lambda(l)-olam(l)
  1208.       sml=1.0-1.0/byg
  1209.       if (dabs(delta).lt.sml*dabs(biga)) byg=biga/(biga-delta)
  1210.       if(delta) 21,7,22
  1211. 21    bound=dmax1(lambda(l)*0.5d0,1.0d0/en)
  1212.       if(bound.lt.-delta*byg) byg=-bound/delta
  1213.       go to 7
  1214. 22    bound=dmin1((1.0d0-lambda(l))*0.5d0,(en-1.0d0)/en)
  1215.       if(bound.lt.delta*byg) byg=bound/delta
  1216. 7     continue
  1217. 8     do 12 l=2,ntypes
  1218.       if(mu(1,l).lt. 1.0d0) mu(1,l)=1.0d0
  1219.       olam(l)=lambda(l)
  1220.       lambda(l)=lambda(l)+byg*(mu(1,l)/en-lambda(l))
  1221.       lambda(l)=dmax1(1.0d-1/en,lambda(l))
  1222.       ij=0
  1223.       do 9 i=1,nvbles
  1224.       biga=mean(i,l)-omean(i,l)
  1225.       bigc=mu(i+1,l)/mu(1,l)-mean(i,l)
  1226.       big=bigest
  1227.       if (dabs(bigc).lt.small*dabs(biga)) big=biga/(biga-bigc)
  1228.       if (method.gt.0) big=1.0
  1229.       omean(i,l)=mean(i,l)
  1230. 9     mean(i,l)=mean(i,l)+big*bigc
  1231.       if(normap) go to 12
  1232.       kj=nvbles+1
  1233.       do 10 i=1,nvbles
  1234.       do 10 j=i,nvbles
  1235.       ij=ij+1
  1236.       kj=kj+1
  1237. 10    covin(ij,l)=(mu(kj,l)-mu(i+1,l)*mean(j,l)-mu(j+1,l)*mean(i,l))/mu(
  1238.      11,l)+mean(i,l)*mean(j,l)
  1239. 12    continue
  1240.       method=iabs(method-1)
  1241.       if (likly.lt.oldlik) method=luck
  1242.       if(.not.normap) return
  1243.       do 11 i=1,nvbles
  1244.       do 11 j=i,nvbles
  1245.       ij=ij+1
  1246.       covin(ij,2)=covin(ij,1)+mean(i,1)*mean(j,1)
  1247.       do 11 l=2,ntypes
  1248. 11    covin(ij,2)=covin(ij,2)-mu(i+1,l)*mu(j+1,l)/(mu(1,l)*en)
  1249.       return
  1250.       end
  1251.       subroutine moment (mean,covin,x,r,s,b,g,mu,v)
  1252.       implicit real*8 (a-h,o-z)
  1253.       real*8 mean,mu,likly
  1254.       real*4 x
  1255.       logical normap
  1256.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1257.       dimension mean(1),covin(1),x(1),r(1),s(1),b(1),g(1),mu(1),v(1)
  1258. c     This routine computes
  1259. c     mu(1,l)= sum over all individuals of their probabilities of
  1260. c     membership in type l.
  1261. c     mu(i+1,l)= sum over all individuals of their x(i,k)
  1262. c     times their probability of membership in type l.
  1263. c     mu(ij,l) = sum over all individuals of their x(i,k)*x(j,k)
  1264. c     times their probability of membership in type l.
  1265. c     g(l)=probability of membership in type l,
  1266. c
  1267. c
  1268. c     This subroutine contains the most deeply nested loops of the
  1269. c     entire normix program.  The following tricks are used
  1270. c     to improve object code efficiency:
  1271. c     --- The routine computes its own indexes for the
  1272. c     doubly-indexed arrays instead of depending on the compiler.
  1273. c     x(ik)  is  x(i,k)
  1274. c     mean(il)   is mean (i,l)
  1275. c     covin(m) is covin(i,j,l)
  1276. c     mu(ij)  is mu(i,j,l)
  1277.       do 12 k=1,nsampl
  1278.             call densit(mean,covin,x,r,s,b,v,g,k)
  1279.       if(normap) go to 44
  1280.       ij=nparam
  1281.       do 11 l=2,ntypes
  1282.       pm=g(l)
  1283.       ia=ij+1
  1284.       ij=ia+nvbles
  1285.       mu(ia)=pm+mu(ia)
  1286.       do 11 i=1,nvbles
  1287.       z=r(i)*pm
  1288.       ia=ia+1
  1289.       mu(ia)=z+mu(ia)
  1290.       do 11 j=i,nvbles
  1291.       ij=ij+1
  1292. 11    mu(ij)=mu(ij)+z*r(j)
  1293.       go to 12
  1294. 44    ia=nparam
  1295.       do 46 l=2,ntypes
  1296.       pm=g(l)
  1297.       ia=ia+1
  1298.       mu(ia)=pm+mu(ia)
  1299.       do 46 i=1,nvbles
  1300.       ia=ia+1
  1301. 46    mu(ia)=r(i)*pm+mu(ia)
  1302. 12    continue
  1303.       return
  1304.       end
  1305.       subroutine tytle
  1306.       implicit real*8 (a-h,o-z)
  1307.       real*8 likly
  1308.       character*60 fmt
  1309.       logical normap
  1310.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1311.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1312.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1313.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1314.      3,method,incase,ntyp(20)
  1315.       write (12,1)
  1316.       if(normap) write (12,2)
  1317.       write (12,3)title
  1318.       return
  1319. c
  1320. c
  1321. 1     format (1h ,42x,'PC-NORMIX  Version 2.1',/,25x,
  1322.      *'Wolfe Normal Mixture Analysis Procedure (January 1995 Revision)')
  1323. 2     format(31x,'Equal Covariance Matrices Within Groups')
  1324. 3     format(//4(1x, 9a8/))
  1325.       end
  1326.       subroutine output (lambda,mean,covin,r,s)
  1327.       implicit real*8 (a-h,o-z)
  1328.       real*8 lambda,mean,likly
  1329.       character*60 fmt
  1330.       logical normap
  1331.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1332.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1333.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1334.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1335.      3,method,incase,ntyp(20)
  1336.       dimension mean(nvbles,2), covin(nsemi,2), lambda(1), r(1), s(1)
  1337.       call tytle
  1338.       ntp=ntypes-1
  1339.       ktypes=ntypes
  1340.       if(normap) ktypes=2
  1341. c     write (*,9) nsampl,nvbles,ntp,iter,ntp,likly
  1342.       write (12,9) nsampl,nvbles,ntp,iter,ntp,likly
  1343.       do 8 l=1,ktypes
  1344.       if (l-1) 1,1,2
  1345. 1     write (12,10)
  1346.       go to 3
  1347. 2     ltyp=l-1
  1348.       if(normap) go to 20
  1349.       write (12,11) ltyp,lambda(l)
  1350.       go to 3
  1351. 20    write (12,21)
  1352.  3    lqq=1
  1353.       do 4 i=1,nvbles
  1354.       s(i)=dsqrt(covin(lqq,l))
  1355. 4     lqq=lqq+nvbles-i+1
  1356.       if(normap.and.l.ne.1) go to 28
  1357.       write (12,12) (i,i=1,nvbles)
  1358.       write (12,13)(mean(i,l),i=1,nvbles)
  1359. 28    write (12,14) (i,i=1,nvbles)
  1360.       write (12,13) (s(i),i=1,nvbles)
  1361.       write (12,15) (i,i=1,nvbles)
  1362.       do 8 i=1,nvbles
  1363.       kj=i-1
  1364.       ij=i
  1365.       if (kj.eq.0) go to 6
  1366.       do 5 j=1,kj
  1367.       r(j)=covin(ij,l)/(s(i)*s(j))
  1368. 5     ij=ij+nvbles-j
  1369. 6     do 7 j=i,nvbles
  1370.       r(j)=covin(ij,l)/(s(i)*s(j))
  1371. 7     ij=ij+1
  1372. 8     write (12,13) (r(j),j=1,nvbles)
  1373.       if(.not. normap) return
  1374.       write (12,16) (i,i=1,nvbles)
  1375.       do 29 l=2,ntypes
  1376.       ltyp=l-1
  1377. 29    write (12,17) ltyp,lambda(l),(mean(i,l),i=1,nvbles)
  1378.       return
  1379. c
  1380. c
  1381. 9     format (/10x,'Sample Size =',i11,/,10x,'Number of Variables =',i3,
  1382.      1/,10x,'Number of Types =',i7,//25x,'Iteration Number',i4,//3x,
  1383.      2'Log Likelihood of',i3,' Types in this sample =',g20.8,/)
  1384. 10    format (20x,'Characteristics of the Whole Sample',//)
  1385. 11    format (/20x,'Characteristics of Type',i4,//15x,'The Proportion of
  1386.      1 the Population from this Type=',f6.3/)
  1387. 12    format (34x,'Means',/10(i8,9i12,/))
  1388. 13    format (10f12.4)
  1389. 14    format (/27x,'Standard Deviations',/10(i8,9i12,/))
  1390. 15    format (/32x,'Correlations',/10(i8,9i12,/))
  1391. 21    format (//20x,'Within-group Standard Deviations and Correlations')
  1392. 16    format (//30x,'Means',/' Type Lambda',i6,9i10,/10(12x,i6,9i10,/))
  1393. 17    format (i4,f8.4,10f10.4/10(12x,10f10.4/))
  1394.       end
  1395.       subroutine dumper (lambda,mean,covin,r,s)
  1396.       implicit real*8 (a-h,o-z)
  1397.       real*8 lambda,mean,likly
  1398.       character*60 fmt
  1399.       character*40 fname
  1400.       logical normap
  1401.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1402.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1403.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1404.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1405.      3,method,incase,ntyp(20)
  1406.       dimension mean(nvbles,2), covin(nsemi,2), lambda(1), r(1), s(1)
  1407.       n=2
  1408. c     This routine writes parameters to a file in format readable by the
  1409. c     subroutine initle.
  1410.       fname ='dumpout'
  1411.       call openit(kpun,fname)
  1412.       do 5 l=2,ntypes
  1413.       if(.not. normap) n=l
  1414.       ltyp=l-1
  1415.       write(kpun,6) lambda(l),ltyp
  1416.       write(kpun,7) (mean(i,l),i=1,nvbles)
  1417.       lqq=1
  1418.       do 1 i=1,nvbles
  1419.       s(i)=dsqrt(covin(lqq,n))
  1420. 1     lqq=lqq+nvbles-i+1
  1421.       write(kpun,7) (s(i),i=1,nvbles)
  1422.       do 5 i=1,nvbles
  1423.       kj=i-1
  1424.       ij=i
  1425.       if (kj.eq.0) go to 3
  1426.       do 2 j=1,kj
  1427.       r(j)=covin(ij,n)/(s(i)*s(j))
  1428. 2     ij=ij+nvbles-j
  1429. 3     do 4 j=i,nvbles
  1430.       r(j)=covin(ij,n)/(s(i)*s(j))
  1431. 4     ij=ij+1
  1432. 5     write(kpun,7) (r(j),j=1,nvbles)
  1433.       return
  1434. c
  1435. 6     format (f8.4,5x,'type',i3)
  1436. 7     format (10f8.4)
  1437.       end
  1438.       subroutine densit (mean,covin,x,r,s,b,v,g,k)
  1439.       implicit real*8 (a-h,o-z)
  1440.       real*8 mean,likly
  1441.       real*4 x
  1442.       character*60 fmt
  1443.       logical normap
  1444.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1445.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1446.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1447.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1448.      3,method,incase,ntyp(20)
  1449.       dimension mean(1),covin(1),x(1),r(1),s(1),b(1),g(2),v(1)
  1450.       if(k .gt. 1) go to 50
  1451.       xlimit=40.0d0
  1452.       n=nvbles-1
  1453.       assign 3 to lone
  1454.       if (n.eq.0) assign 6 to lone
  1455.       ik=1
  1456. 50    eph=0.0d0
  1457.       do 1 i=1,nvbles
  1458.       r(i)=x(ik)
  1459. 1     ik=ik+1
  1460.       il=nvbles
  1461.       if(normap) go to 40
  1462.       ij=nsemi
  1463.       do 7 l=2,ntypes
  1464.       do 2 i=1,nvbles
  1465.       il=il+1
  1466. 2     s(i)=r(i)-mean(il)
  1467.       dsqrd=  b(l)
  1468.       go to lone, (3,6)
  1469. 3     do 5 i=1,n
  1470.       ij=ij+1
  1471.       cute=s(i)*covin(ij)
  1472.       do 4 j=i,n
  1473.       ij=ij+1
  1474. 4     cute=cute+covin(ij)*s(j+1)
  1475. 5     dsqrd=dsqrd-cute*s(i)
  1476. 6     ij=ij+1
  1477. 7     g(l)=dsqrd-covin(ij)*s(nvbles)**2
  1478.       go to 43
  1479. 40    do 42 l=2,ntypes
  1480.       dsqrd= b(l)
  1481.       do 41 i=1,nvbles
  1482.       il=il+1
  1483. 41    dsqrd=dsqrd+v(il)*r(i)
  1484. 42    g(l)=dsqrd
  1485. 43    biga=g(2)
  1486.       lot=2
  1487.       bigb=biga
  1488.       if (ntypes.eq.2) go to 13
  1489.       do 9 l=3,ntypes
  1490.       if (g(l).le.bigb) go to 9
  1491.       if (g(l).le.biga) go to 8
  1492.       bigb=biga
  1493.       biga=g(l)
  1494.       lot=l
  1495.       go to 9
  1496. 8     bigb=g(l)
  1497. 9     continue
  1498.       if ((biga-bigb).gt.xlimit) go to 13
  1499.       g(lot)=1.0d0
  1500.       do 10 l=2,ntypes
  1501.       if (l.eq.lot) go to 10
  1502.       dsqrd=g(l)-biga
  1503.       g(l)=0.0d0
  1504.       if (dsqrd.gt.-4d1   ) g(l)=dexp(dsqrd)
  1505. 10    eph=eph+g(l)
  1506.       likly=likly+dlog(eph)+biga
  1507.       do 11 l=2,ntypes
  1508. 11    g(l)=g(l)/eph
  1509.       return
  1510. c     Consider the probability of membership to be one for nearest type
  1511. 13    likly=likly+biga
  1512.       do 14 l=2,ntypes
  1513. 14    g(l)=0.0d0
  1514.       g(lot)=1.0d0
  1515.       return
  1516.       end
  1517. c ***********************************************************************
  1518.       subroutine assign(lambda,mean,covin,x,r,s,b,v,g,mu,t,w,bmat,case)
  1519. c     This routine prints the probabilities of membership of each
  1520. c     individual in each type.
  1521. c     It computes and prints discriminant functions and each individuals
  1522. c     discriminant scores.
  1523. c      Discriminant analysis.  See the following references
  1524. c     Cooley+Lohnes. Multivariate Proced.Behav.Sciences  pages 117,189.
  1525. c     Friedman and Rubin. Journ. Am. Stat. Assn. 1967, page 1167.
  1526. c
  1527.       implicit real*8 (a-h,o-z)
  1528.       real*8 lambda,mean,mu,likly
  1529.       real*4 x
  1530.       integer is(12)
  1531.       character*72 fmtx1,fmtx2,fmtx3,fmtx4,fmtx5,fmtx6,fmtx7
  1532.       character char*1,idstrng*3,fmt*60
  1533.       character*24 alph,id(12)          
  1534.       logical*1 case(24,nsampl),lchar
  1535.       logical normap,newhead
  1536.  
  1537.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1538.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1539.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1540.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1541.      3,method,incase,ntyp(20)
  1542.       dimension covin(nsemi,1),lambda(1),g(1),r(nrank),s(1),mean(1),b(1)
  1543.      1,v(1),t(nvbles,nvbles),w(nvbles,nvbles),bmat(nvbles,nvbles),
  1544.      1 x(nvbles,1),mu(nparam,1)
  1545.       equivalence (char,lchar)      
  1546. c           
  1547.       call itime(itmda)
  1548.       kc=3
  1549.       rewind kc
  1550.       al=likly
  1551.       if(normap) then
  1552.         mrank= min0(ntypes-2,nvbles)
  1553.          ij=0
  1554.          do 10 i=1,nvbles
  1555.          do 10 j=i,nvbles
  1556.             ij=ij+1
  1557.             w(i,j)=covin(ij,2)
  1558.             bmat(i,j)=covin(ij,1)-covin(ij,2)
  1559.    10   bmat(j,i)=bmat(i,j)
  1560. c        bmat is the between-group covariance matrix
  1561. c        w is the within-group covariance matrix
  1562.          call nroot(nvbles,bmat,w,r,t)
  1563.          call tytle
  1564.          write (12,3000)(l,l=1,mrank)
  1565.  3000   format (//25x,'Discriminant Functions',/(16x,10i10))
  1566.  
  1567.          do 20 i=1,nvbles
  1568.    20   write (12,3010) i,(t(i,l),l=1,mrank)
  1569.  3010    format (' Variable',i4,7x,10f10.4/(20x,10f10.4))
  1570.  
  1571.          write (12,3020) (r(l),l=1,mrank)
  1572.  3020   format (/' Eigenvalues of B/W=',10f10.4)
  1573.       
  1574.          call itime(itmdb)
  1575.          tmd=(itmdb-itmda)/100.0
  1576. c        write (12,3030)tmd
  1577. c3030    format(//40x,'Time to Compute Discriminant Functions =',f8.2,
  1578. c    1' seconds.')
  1579.       else      
  1580.          lqq=nsemi
  1581.          do 40 l=2,ntypes
  1582.          ij=0
  1583.          do 30 i=1,nvbles
  1584.          do 30 j=i,nvbles
  1585.          ij=ij+1
  1586.    30    mu(ij,l)=covin(ij,l)
  1587.          call syminv (covin,nvbles,detm,r,s,g,lqq)
  1588.            b(l)=dlog(lambda(l))-0.5*detm
  1589.    40    lqq=lqq+nsemi
  1590.          iii=nvbles
  1591.          ii=1
  1592.          do 60 i=1,nvbles
  1593.          do 50 l=2,ntypes
  1594.    50   covin(ii,l)=covin(ii,l)/2.0
  1595.          ii=ii+iii
  1596.    60 iii=iii-1
  1597.       endif
  1598.  
  1599.       likly=0.0d0
  1600.       ntp=ntypes-1
  1601.       if(incase .gt. 0) idstrng = ' ID'
  1602.       if(incase .eq. 0) idstrng = '   '
  1603.       m1 = (100-incase)/6
  1604.       lineper = (ntp + m1 -1)/m1      
  1605.       m3 = 20 + incase
  1606.       m4 = 5
  1607.       m5 = max0(1,incase/3)
  1608.       m5r = max0(1,incase - m5)
  1609.       m6 = 120/(13+incase)
  1610.       m7 = m5 + m5r
  1611.        
  1612. c     Setup format fmtx1 for probability title.
  1613.          write(unit=fmtx1,fmt=3040)m5+1,(incase+12)
  1614.  3040 format('(8h   Seq.#,',i2,'x,a3,t',i2.2,',7hCluster,8x,',
  1615.      * '24hMembership Probabilities)')
  1616.  
  1617. c     Setup format fmtx2 for discriminant score title.     
  1618.          if(normap) write(unit=fmtx2,fmt=3050)m5+1,(incase+12)
  1619.  3050 format('(8h   Seq.#,',i2,'x,a3,t',i2.2,',7hCluster,8x,',
  1620.      * '19hDiscriminant Scores)')
  1621.  
  1622. c     Setup format fmtx3 for cluster numbers at top of table.   
  1623.          write(unit=fmtx3,fmt=3060)(incase+19),m1
  1624.  3060    format( '(t',i2.2,',',i2,'i6)' )
  1625. c     Setup format fmtx4 for probabilities or discriminant scores.
  1626.          if(incase .eq. 0) then
  1627.             fmtx4 = '(i6,i9,4x,16f6.3,:,(/19x,16f6.3,:))'
  1628.             fmtx5 = '(i6,i9,4x,16f6.2,:,(/19x,16f6.2,:))'            
  1629.          else
  1630.             write(unit=fmtx4,fmt=3070)incase,m1,m3,m1
  1631.  3070       format('(i6,3x,a',i2.2,',i7,4x,',i2,'f6.3,:, (/',i2.2,'x,',
  1632.      *               i2,'f6.3,:))')
  1633.             write(unit=fmtx5,fmt=3080)incase,m1,m3,m1
  1634.  3080       format('(i6,3x,a',i2.2,',i7,4x,',i2,'f6.2,:, (/',i2.2,'x,',
  1635.      *               i2,'f6.2,:))')
  1636.       endif
  1637. c     Set up format for printing case lists sorted by cluster.
  1638.       write(fmtx6,4020)m6,m5 ,m5r
  1639.  4020 format( '(',i2,'(8h    Seq#,',i2,'x,a3,',i2,'x))' )
  1640.       if(incase .eq. 0) then
  1641.          write(fmtx7,4030)m6,m7
  1642.  4030    format('(',i2,'(i8,3x,',i2,'x))')
  1643.       else
  1644.          write(fmtx7,4040)m6,incase
  1645.  4040    format('(',i2,'(i8,3x,a',i2.2,'))')
  1646.       endif
  1647.  
  1648.  
  1649. c      write(12,*)' fmtx1=',fmtx1    
  1650. c      write(12,*)' fmtx2=',fmtx2  
  1651. c      write(12,*)' fmtx3=',fmtx3
  1652. c      write(12,*)' fmtx4=',fmtx4
  1653. c      write(12,*)' fmtx5=',fmtx5
  1654. c      write(12,*)' fmtx6=',fmtx6
  1655. c      write(12,*)' fmtx7=',fmtx7                        
  1656. c *****************************************************************   
  1657.       do 100 k=1,nsampl
  1658. c     if line count > 44, then start a new page.
  1659.       if(mod(k,45/lineper) .eq. 1) then
  1660.          call tytle            
  1661.          write (12,fmtx1)idstrng 
  1662.          write (12,3090)
  1663. 3090      format( 1h  )
  1664. c   
  1665.          write (12,fmtx3) (i,i=1,ntypes-1)
  1666.          write (12,3090)
  1667.       endif
  1668.       
  1669.       if(incase .gt. 0) then
  1670. c     Copy case ==> alph
  1671.          do 70 i=1,incase
  1672.             lchar = case(i,k)
  1673.    70    alph(i:i) = char
  1674.       endif      
  1675.  
  1676. c     Compute the membership probabilities
  1677.       call densit (mean,covin,x,r,s,b,v,g,k)
  1678. c     Find the largest probability, and assign case.
  1679.       xmax=0
  1680.       do 80 l=2,ntypes        
  1681.          if (g(l).lt.xmax) go to 80
  1682.          lot=l
  1683. c         lot = the most probable type for individual k.
  1684.          xmax=g(l)
  1685.    80 continue
  1686.       lit = lot -1
  1687. c     If normap, then compute discriminant scores.   
  1688.       if(normap) then
  1689.          do 90 l=1,nrank
  1690.          r(l)=0.0
  1691.          do 90 i=1,nvbles
  1692.    90    r(l)=r(l)+t(i,l)*(x(i,k)-mean(i))
  1693.          write(kc)k,lot,(r(i),i=1,nrank)
  1694.  
  1695. c     Save discriminant scores on tape, in card-image format.      
  1696.          write(kscrat,4000)k,lit,(r(i),i=1,nrank)
  1697.  4000    format (i6,i4,10f7.2)
  1698.       else
  1699.          write(kc)k,lot
  1700.       endif
  1701.  
  1702. c     Printout probabilities of membership
  1703.          if(incase .eq. 0) then
  1704.                write(12,fmtx4)k,lit,(g(i),i=2,ntypes)
  1705.          else
  1706.                write(12,fmtx4)k,alph,lit,(g(i),i=2,ntypes)
  1707.          endif
  1708.  
  1709.   100 continue
  1710.       likly=al
  1711.       if(normap) then
  1712. c *****************************************************************
  1713. c     Print the discriminant scores
  1714.       rewind kc
  1715.       do 120 k=1,nsampl
  1716. c     Start a new page if the line count > 44.
  1717.       if(mod(k,45) .eq. 1) then
  1718.          call tytle            
  1719.          write (12,fmtx2)idstrng
  1720.          write (12,3090)
  1721. c   
  1722.          write (12,fmtx3) (i,i=1,nrank)
  1723.          write (12,3090)
  1724.       endif
  1725.       if(incase .gt. 0) then
  1726. c     Copy case ==> alph
  1727.          do 110 i=1,incase
  1728.             lchar = case(i,k)
  1729.   110    alph(i:i) = char
  1730.       endif
  1731. c     Read the cluster and discriminant scores from unit kc.
  1732.       read(kc)kk,lot,(r(i),i=1,nrank)
  1733.       lit = lot -1
  1734. c     Print the current case.
  1735.       if(incase .eq. 0) then   
  1736.          write(12,fmtx5)k,lit,(r(i),i=1,nrank)
  1737.       else
  1738.          write(12,fmtx5)k,alph,lit,(r(i),i=1,nrank)
  1739.       endif
  1740.   120 continue
  1741. c     If not normap, then
  1742.       else
  1743.          do 130  l=2,ntypes
  1744.          do 130 i=1,nsemi
  1745.   130    covin(i,l)=mu(i,l)
  1746.       endif
  1747. c**********************************************************************
  1748. c     Print case numbers and IDs for each cluster.
  1749.       lap=45
  1750.       do 160 lotpas=1,ntp
  1751.       ik = 0
  1752.       newhead = .true.
  1753.       rewind kc
  1754. c     Search through all the cases, looking for ones in this cluster.      
  1755.       do 150 k=1,nsampl
  1756. c        Print new page if line count > 44.
  1757.       if(lap .ge. 45) then
  1758.             lap = 0
  1759.             call tytle
  1760.             newhead = .true.
  1761.          endif
  1762. c     Read cluster memberships from unit kc.
  1763.       if(normap) then
  1764.          read(kc)kk,lot,(r(i),i=1,nrank)
  1765.       else
  1766.          read(kc)kk,lot
  1767.       endif
  1768.       lit = lot -1
  1769. c     If this case is a member of the current cluster being printed,
  1770. c     store it in the row to be printed.
  1771.       if(lit .eq. lotpas) then
  1772.          ik = ik + 1
  1773.          is(ik) = k
  1774.          if(incase .gt. 0) then
  1775. c           Copy case ==> alph
  1776.             do 140 i=1,incase
  1777.                lchar = case(i,k)
  1778.   140       alph(i:i) = char     
  1779.             id(ik) = alph
  1780.          endif
  1781.       endif
  1782. c     Is it time to print the row?
  1783.       if((ik .eq. m6) .or. ((k .eq. nsampl) .and. (ik .gt. 0) )) then
  1784. c        Print Cluster headers if new page or new cluster.
  1785.          if(newhead) then
  1786.             write(12,4050)lotpas
  1787.  4050       format(/,30x,'Members of Cluster', i3)
  1788.             write (12,3090)            
  1789.             write(12,fmtx6)(idstrng,i=1,m6)
  1790.             write (12,3090)
  1791.             newhead = .false.
  1792.             lap = lap + 5            
  1793.          endif      
  1794.          if(incase .gt. 0) then
  1795.             write(12,fmtx7)(is(i),id(i),i=1,ik)
  1796.          else
  1797.             write(12,fmtx7)(is(i),i=1,ik)
  1798.          endif
  1799.          ik = 0
  1800.          lap = lap+1
  1801.       endif
  1802.   150 continue
  1803.   160 continue              
  1804.       return
  1805. c
  1806.       end
  1807. c    
  1808.       subroutine mapper(matrix,r,b)
  1809.       implicit real*8 (a-h,o-z)
  1810.       real*8 likly
  1811.       character*60 fmt
  1812.       logical normap
  1813.       common/a/likly,xlimit,nvbles,nsampl,ntypes,nsemi,nparam,normap,kx
  1814.       common/b/convrg,critrn,ratio,htest,oldlik,en,bigest,thresh,guard,
  1815.      1enmin,title(36),fmt,mxhier,maxtyp,maxav,nclust,kscrat,inp,kpun,kv,
  1816.      2 lot,lack,luck,iprint,ltime,maxt,iter,iterx,ltye,itmc,nrank,ivalue
  1817.      3,method,incase,ntyp(20)
  1818. c     The next three lines are necessary because PowerStation 
  1819. c     FORTRAN cannot pass real arrays to character arrays in subr. call. 
  1820.       logical*1 kblk,kper,kstr,lim,lookup(20),matrix(120,50),mlog
  1821.       character*1 mchar,blnk,clim,str
  1822.       equivalence (mlog,mchar),(kblk,blnk),(kstr,str),(lim,clim)
  1823.       dimension  r(nrank),b(21)
  1824.       data  lookup/'1','2','3','4','5','6','7','8','9','A','B','C','D',
  1825.      1 'E','F','G','H','I','J','K' /,kblk/' ' /,kper/'.' /,kstr/'*' /
  1826. c     This routine reads the file of discriminant scores and produces a
  1827. c     semi-graphical display on the printout.
  1828.       kc=3
  1829.       if(nrank.le.1) return
  1830.       ltypes=ntypes-1
  1831.       do 10 i=1,2
  1832.       i1=i+1
  1833.       if(i1.gt.nrank) go to 11
  1834.       do 10 j=i1,nrank
  1835.       do 2 m=1,48
  1836.       do 2 n=1,116
  1837. 2     matrix(n,m)=kblk
  1838.       do 3 m=1,48
  1839. 3     matrix(1,m)=kper
  1840.       do 4 n=1,116
  1841. 4     matrix(n,47)=kper
  1842.       rewind kc
  1843.       do 5 k=1,nsampl
  1844.       read(kc)l,key,(r(ir),ir=1,nrank)
  1845.       m=5.0*r(i)+58.
  1846.       n=-3.0*r(j)+23.
  1847.       m= max0(2,min0(m,116))
  1848.       n= max0(2,min0(n, 46))
  1849.       lim=lookup(key-1)       
  1850.       mlog = matrix(m,n)
  1851. c     if (matrix(m,n).ne. kblk) go to 5   [Not valid for PowerStation]
  1852.       if (mchar .eq. blnk) go to 5
  1853. c     if (matrix(m,n).ne. lim) lim=kstr   [Not valid for PowerStation]
  1854.       if (mchar .eq. clim) clim = str
  1855. 5     matrix(m,n)=lim
  1856.       call tytle
  1857.       write (12,13) j,ltypes
  1858.       ly=8
  1859.       lb=1
  1860.       do 8 n=1,47
  1861.       lb=lb+1
  1862.       go to (7,7,6), lb
  1863. 6     lb=0
  1864.       ly=ly-1
  1865.       write (12,14) ly,(matrix(m,n),m=1,116)
  1866.       go to 8
  1867. 7     write (12,15) (matrix(m,n),m=1,116)
  1868. 8     continue
  1869.       xd=-11.0
  1870.       do 9 m=1,21
  1871.       xd=xd+1.0
  1872. 9     b(m)=xd
  1873. 10    write (12,16) (b(m),m=1,21),i
  1874. 11    continue
  1875.       return
  1876. c
  1877. 12    format (6x,i4,10f7.2)
  1878. 13    format (5x,'Discriminant Function',i2,50x,'Number of Types=',i2)
  1879. 14    format (i4,116a1)
  1880. 15    format (4x,116a1)
  1881. 16    format (f12.0,20f5.0/45x,'Discriminant Function',i2)
  1882.       end
  1883.  
  1884.  
  1885.       function chisqp (chisq,ndfree)
  1886.       implicit real*8 (a-h,o-z)
  1887.       a=chisq*0.5
  1888.       t=dexp(-a)
  1889.       nn=(ndfree/2)*2
  1890.       if (nn-ndfree) 2,1,2
  1891. 1     p=t
  1892.       t=a*t
  1893.       kw=4
  1894.       ak=2.0
  1895.       go to 3
  1896. 2     c=dsqrt(chisq)
  1897.       p=2.0*area(c)
  1898.       t=0.7978846*c*t
  1899.       ak=1.5
  1900.       kw=3
  1901. 3     if (ndfree-2) 6,6,4
  1902. 4     do 5 i=kw,ndfree,2
  1903.       p=p+t
  1904.       t=(t*a)/ak
  1905. 5     ak=1.0+ak
  1906. 6     chisqp=p
  1907.       return
  1908.       end
  1909.       function area (w)
  1910. c     area above w on normal curve
  1911.       implicit real*8 (a-h,o-z)
  1912.       x=w*.70710678118654752440
  1913.       kot=2
  1914.       if (x) 1,1,2
  1915. 1     kot=1
  1916.       x=-x
  1917. 2     area=0.5/((((((.0000430638*x+.0002765672)*x+.0001520143)*x+.009270
  1918.      15272)*x+.0422820123)*x+.0705230784)*x+1.0)**16
  1919.       go to (3,4), kot
  1920. 3     area=1.0-area
  1921. 4     return
  1922.       end
  1923.       subroutine uplow(a,n,mode)
  1924. c     changes a symmetric matrix from upper to lower triangular form
  1925. c     or vice versa.
  1926. c     a = an n*n symmetric matrix stored in triangular form as a
  1927. c     one-dimensional array of n*(n+1)/2 elements.
  1928. c
  1929. c     mode = +1 if the input has ibm storage mode 1
  1930. c     mode = -1 if the input has the opposite half of ibm storage mode 1
  1931. c                                 examples
  1932. c              mode = +1                               mode = -1
  1933. c     a(1)   a(2)   a(4)   a( 7)              a(1)   a(2)   a(3)   a( 4)
  1934. c            a(3)   a(5)   a( 8)                     a(5)   a(6)   a( 7)
  1935. c                   a(6)   a( 9)                            a(8)   a( 9)
  1936. c                          a(10)                                   a(10)
  1937. c
  1938.       real*8 a,t
  1939.       dimension a(1)
  1940.       if(n.lt.3) go to 5
  1941.       node= (mode+3)/2
  1942.       nn=n*(n+1)/2
  1943.       n2=n/2
  1944.       nn2=nn/2
  1945.       go to (1,3),node
  1946.     1 k=nn+1
  1947. c     reverse the order of the variables by
  1948. c     interchanging a(i,j) with a(n+1-j,n+1-i)
  1949.       ij=0
  1950.       m=n
  1951.       do 6 i=1,n2
  1952.       m=m-1
  1953.       k=k-i
  1954.       l=k
  1955.       do 2 j=i,m
  1956.       ij=ij+1
  1957.       t=a(ij)
  1958.       a(ij)=a(l)
  1959.       a(l)=t
  1960.     2 l=l-j
  1961.     6 ij=ij+i
  1962.       go to (3,5),node
  1963.     3 l=nn
  1964. c     reverse a, interchanging a(i) with a(nn+1-i)
  1965.       do 4 i=1,nn2
  1966.       t=a(i)
  1967.       a(i)=a(l)
  1968.       a(l)=t
  1969.     4 l=l-1
  1970.       go to (5,1),node
  1971.     5 return
  1972.       end
  1973.       function squad (s,b,mx,ls,lb)
  1974.       implicit real*8 (a-h,o-z)
  1975.       dimension s(1), b(1)
  1976. c     this program calculates the quadratic form squad=bsb/2
  1977. c     where s is a semi-matrix in upper triangular form,b is a vector,
  1978. c     mx= order of matrices
  1979. c     the matrices start at s(ls+1) and b(lb+1)
  1980.       squad=0.0
  1981.       ij=ls
  1982.       n=mx+lb
  1983.       if (mx-1) 5,4,1
  1984. 1     nf=lb+1
  1985.       na=n-1
  1986.       do 3 i=nf,na
  1987.       ij=ij+1
  1988.       cute=b(i)*s(ij)/2.0
  1989.       do 2 j=i,na
  1990.       ij=ij+1
  1991. 2     cute=cute+s(ij)*b(j+1)
  1992. 3     squad=squad+cute*b(i)
  1993. 4     squad=squad+s(ij+1)*b(n)**2/2.0
  1994. 5     return
  1995.       end
  1996.       subroutine syminv (symtrx,norder,determ,rdumy,sdumy,untryd,lbefor)
  1997.       implicit real*8 (a-h,o-z)
  1998.       logical untryd
  1999. c     acm algorithm 150 by h. rutishauser
  2000. c     this program replaces a symmetric matrix by its inverse.
  2001. c     symtrx is the symmetric matrix, stored in upper triangular form as
  2002. c     a one-dimensional array starting at symtrx(lbefor+1)  .
  2003. c     rdumy and sdumy are temporary storage vectors used in the program.
  2004. c     norder is the order of the matrix and the temporary storage areas.
  2005. c     determ= natural logarithm of the determinant
  2006.       dimension symtrx(1), rdumy(1), sdumy(1), untryd(1)
  2007.       determ=0.0
  2008.       do 1 i=1,norder
  2009. c     untryd(i)=1 before i has been used as a pivot, and =0 afterwards.
  2010. 1     untryd(i)=.true.
  2011.       do 7 l=1,norder
  2012. c     search for pivot
  2013.       bigajj=0.0
  2014.       n=lbefor+1
  2015.       do 2 j=1,norder
  2016.       t=dabs(symtrx(n))
  2017.       if (.not.untryd(j).or.t.le.bigajj) go to 2
  2018.       bigajj=t
  2019.       k=j
  2020.       nk=n
  2021. 2     n=n+norder-j+1
  2022.       if (bigajj.le.1.0e-50) symtrx(nk)=1.0e-50
  2023.       determ=determ+dlog(dabs(symtrx(nk)))
  2024. c      sweeps out the symmetric matrix symtrx for a selected pivot k,
  2025. c     resulting in the so-called partial inverse useful in stepwise
  2026. c     regression.
  2027.       untryd(k)=.false.
  2028. c     preparation of elimination step
  2029.       rdumy(k)=1.0/symtrx(nk)
  2030.       sdumy(k)=1.0
  2031.       symtrx(nk)=0.0
  2032.       n=lbefor+k
  2033.       if (k.eq.1) go to 4
  2034.       ka=k-1
  2035.       do 3 j=1,ka
  2036.       sdumy(j)=symtrx(n)
  2037.       rdumy(j)=symtrx(n)*rdumy(k)
  2038.       if (untryd(j)) rdumy(j)=-rdumy(j)
  2039.       symtrx(n)=0.0
  2040. 3     n=n+norder-j
  2041. 4     if (k.eq.norder) go to 6
  2042.       ka=k+1
  2043.       do 5 j=ka,norder
  2044.       n=n+1
  2045.       sdumy(j)=symtrx(n)
  2046.       rdumy(j)=-symtrx(n)*rdumy(k)
  2047.       if (.not.untryd(j)) sdumy(j)=-sdumy(j)
  2048. 5     symtrx(n)=0.0
  2049. c     elimination proper
  2050. 6     n=lbefor
  2051.       do 7 i=1,norder
  2052.       do 7 j=i,norder
  2053.       n=n+1
  2054. 7     symtrx(n)=symtrx(n)+sdumy(i)*rdumy(j)
  2055.       return
  2056.       end
  2057. c
  2058. c     ..................................................................
  2059. c
  2060. c        subroutine eigen
  2061. c
  2062. c        purpose
  2063. c           compute eigenvalues and eigenvectors of a real symmetric
  2064. c           matrix
  2065. c
  2066. c        usage
  2067. c           call eigen(a,r,n,mv)
  2068. c
  2069. c        description of parameters
  2070. c           a - original matrix (symmetric), destroyed in computation.
  2071. c               resultant eigenvalues are developed in diagonal of
  2072. c               matrix a in descending order.
  2073. c           r - resultant matrix of eigenvectors (stored columnwise,
  2074. c               in same sequence as eigenvalues)
  2075. c           n - order of matrices a and r
  2076. c           mv- input code
  2077. c                   0   compute eigenvalues and eigenvectors
  2078. c                   1   compute eigenvalues only (r need not be
  2079. c                       dimensioned but must still appear in calling
  2080. c                       sequence)
  2081. c
  2082. c        remarks
  2083. c           original matrix a must be real symmetric (storage mode=1)
  2084. c           matrix a cannot be in the same location as matrix r
  2085. c
  2086. c        subroutines and function subprograms required
  2087. c           none
  2088. c
  2089. c        method
  2090. c           diagonalization method originated by jacobi and adapted
  2091. c           by von neumann for large computers as found in 'mathematical
  2092. c           methods for digital computers', edited by a. ralston and
  2093. c           h.s. wilf, john wiley and sons, new york, 1962, chapter 7
  2094. c
  2095. c     ..................................................................
  2096. c
  2097.       subroutine eigen(a,r,n,mv)
  2098.       dimension a(1),r(1)
  2099. c
  2100. c        ...............................................................
  2101. c
  2102. c        if a double precision version of this routine is desired, the
  2103. c        c in column 1 should be removed from the double precision
  2104. c        statement which follows.
  2105. c
  2106.       double precision a,r,anorm,anrmx,thr,x,y,sinx,sinx2,cosx,
  2107.      1                 cosx2,sincs,range
  2108. c
  2109. c        the c must also be removed from double precision statements
  2110. c        appearing in other routines used in conjunction with this
  2111. c        routine.
  2112. c
  2113. c        the double precision version of this subroutine must also
  2114. c        contain double precision fortran functions.  sqrt in statements
  2115. c        40, 68, 75, and 78 must be changed to dsqrt.  abs in statement
  2116. c        62 must be changed to dabs. the constant in statement 5 should
  2117. c        be changed to 1.0d-12.
  2118. c
  2119. c        ...............................................................
  2120. c
  2121. c        generate identity matrix
  2122. c
  2123.     5 range=1.0d-12
  2124.       if(mv-1) 10,25,10
  2125.    10 iq=-n
  2126.       do 20 j=1,n
  2127.       iq=iq+n
  2128.       do 20 i=1,n
  2129.       ij=iq+i
  2130.       r(ij)=0.0
  2131.       if(i-j) 20,15,20
  2132.    15 r(ij)=1.0
  2133.    20 continue
  2134. c
  2135. c        compute initial and final norms (anorm and anormx)
  2136. c
  2137.    25 anorm=0.0
  2138.       do 35 i=1,n
  2139.       do 35 j=i,n
  2140.       if(i-j) 30,35,30
  2141.    30 ia=i+(j*j-j)/2
  2142.       anorm=anorm+a(ia)*a(ia)
  2143.    35 continue
  2144.       if(anorm) 165,165,40
  2145.    40 anorm=1.414d0*dsqrt(anorm)
  2146.       anrmx=anorm*range/dble(n)
  2147. c
  2148. c        initialize indicators and compute threshold, thr
  2149. c
  2150.       ind=0
  2151.       thr=anorm
  2152.    45 thr=thr/dble(n)
  2153.    50 l=1
  2154.    55 m=l+1
  2155. c
  2156. c        compute sin and cos
  2157. c
  2158.    60 mq=(m*m-m)/2
  2159.       lq=(l*l-l)/2
  2160.       lm=l+mq
  2161.    62 if(dabs(a(lm))-thr) 130,65,65
  2162.    65 ind=1
  2163.       ll=l+lq
  2164.       mm=m+mq
  2165.       x=0.5*(a(ll)-a(mm))
  2166.    68 y=-a(lm)/dsqrt(a(lm)*a(lm)+x*x)
  2167.       if(x) 70,75,75
  2168.    70 y=-y
  2169.    75 sinx=y/dsqrt(2.0*(1.0+(dsqrt(1.0-y*y))))
  2170.       sinx2=sinx*sinx
  2171.    78 cosx=dsqrt(1.0-sinx2)
  2172.       cosx2=cosx*cosx
  2173.       sincs =sinx*cosx
  2174. c
  2175. c        rotate l and m columns
  2176. c
  2177.       ilq=n*(l-1)
  2178.       imq=n*(m-1)
  2179.       do 125 i=1,n
  2180.       iq=(i*i-i)/2
  2181.       if(i-l) 80,115,80
  2182.    80 if(i-m) 85,115,90
  2183.    85 im=i+mq
  2184.       go to 95
  2185.    90 im=m+iq
  2186.    95 if(i-l) 100,105,105
  2187.   100 il=i+lq
  2188.       go to 110
  2189.   105 il=l+iq
  2190.   110 x=a(il)*cosx-a(im)*sinx
  2191.       a(im)=a(il)*sinx+a(im)*cosx
  2192.       a(il)=x
  2193.   115 if(mv-1) 120,125,120
  2194.   120 ilr=ilq+i
  2195.       imr=imq+i
  2196.       x=r(ilr)*cosx-r(imr)*sinx
  2197.       r(imr)=r(ilr)*sinx+r(imr)*cosx
  2198.       r(ilr)=x
  2199.   125 continue
  2200.       x=2.0*a(lm)*sincs
  2201.       y=a(ll)*cosx2+a(mm)*sinx2-x
  2202.       x=a(ll)*sinx2+a(mm)*cosx2+x
  2203.       a(lm)=(a(ll)-a(mm))*sincs+a(lm)*(cosx2-sinx2)
  2204.       a(ll)=y
  2205.       a(mm)=x
  2206. c
  2207. c        tests for completion
  2208. c
  2209. c        test for m = last column
  2210. c
  2211.   130 if(m-n) 135,140,135
  2212.   135 m=m+1
  2213.       go to 60
  2214. c
  2215. c        test for l = second from last column
  2216. c
  2217.   140 if(l-(n-1)) 145,150,145
  2218.   145 l=l+1
  2219.       go to 55
  2220.   150 if(ind-1) 160,155,160
  2221.   155 ind=0
  2222.       go to 50
  2223. c
  2224. c        compare threshold with final norm
  2225. c
  2226.   160 if(thr-anrmx) 165,165,45
  2227. c
  2228. c        sort eigenvalues and eigenvectors
  2229. c
  2230.   165 iq=-n
  2231.       do 185 i=1,n
  2232.       iq=iq+n
  2233.       ll=i+(i*i-i)/2
  2234.       jq=n*(i-2)
  2235.       do 185 j=i,n
  2236.       jq=jq+n
  2237.       mm=j+(j*j-j)/2
  2238.       if(a(ll)-a(mm)) 170,185,185
  2239.   170 x=a(ll)
  2240.       a(ll)=a(mm)
  2241.       a(mm)=x
  2242.       if(mv-1) 175,185,175
  2243.   175 do 180 k=1,n
  2244.       ilr=iq+k
  2245.       imr=jq+k
  2246.       x=r(ilr)
  2247.       r(ilr)=r(imr)
  2248.   180 r(imr)=x
  2249.   185 continue
  2250.       return
  2251.       end
  2252. c
  2253. c     ..................................................................
  2254. c
  2255. c        subroutine nroot
  2256. c
  2257. c        purpose
  2258. c           compute eigenvalues and eigenvectors of a real nonsymmetric
  2259. c           matrix of the form b-inverse times a.  this subroutine is
  2260. c           normally called by subroutine canor in performing a
  2261. c           canonical correlation analysis.
  2262. c
  2263. c        usage
  2264. c           call nroot (m,a,b,xl,x)
  2265. c
  2266. c        description of parameters
  2267. c           m  - order of square matrices a, b, and x.
  2268. c           a  - input matrix (m x m).
  2269. c           b  - input matrix (m x m).
  2270. c           xl - output vector of length m containing eigenvalues of
  2271. c                b-inverse times a.
  2272. c           x  - output matrix (m x m) containing eigenvectors column-
  2273. c                wise.
  2274. c
  2275. c        remarks
  2276. c           none
  2277. c
  2278. c        subroutines and function subprograms required
  2279. c           eigen
  2280. c
  2281. c        method
  2282. c           refer to w. w. cooley and p. r. lohnes, 'multivariate pro-
  2283. c           cedures for the behavioral sciences', john wiley and sons,
  2284. c           1962, chapter 3.
  2285. c
  2286. c     ..................................................................
  2287. c
  2288.       subroutine nroot (m,a,b,xl,x)
  2289.       dimension a(1),b(1),xl(1),x(1)
  2290. c
  2291. c        ...............................................................
  2292. c
  2293. c        if a double precision version of this routine is desired, the
  2294. c        c in column 1 should be removed from the double precision
  2295. c        statement which follows.
  2296. c
  2297.       double precision a,b,xl,x,sumv
  2298. c
  2299. c        the c must also be removed from double precision statements
  2300. c        appearing in other routines used in conjunction with this
  2301. c        routine.
  2302. c
  2303. c        the double precision version of this subroutine must also
  2304. c        contain double precision fortran functions.  sqrt in statements
  2305. c        110 and 175 must be changed to dsqrt.  abs in statement 110
  2306. c        must be changed to dabs.
  2307. c
  2308. c        ...............................................................
  2309. c
  2310. c     compute eigenvalues and eigenvectors of b
  2311. c
  2312.       k=1
  2313.       do 100 j=2,m
  2314.       l=m*(j-1)
  2315.       do 100 i=1,j
  2316.       l=l+1
  2317.       k=k+1
  2318.   100 b(k)=b(l)
  2319. c
  2320. c        the matrix b is a real symmetric matrix.
  2321. c
  2322.       mv=0
  2323.       call eigen (b,x,m,mv)
  2324. c
  2325. c     form reciprocals of square root of eigenvalues.  the results
  2326. c     are premultiplied by the associated eigenvectors.
  2327. c
  2328.       l=0
  2329.       do 110 j=1,m
  2330.       l=l+j
  2331.   110 xl(j)=1.0/dsqrt(dabs(b(l)))
  2332.       k=0
  2333.       do 115 j=1,m
  2334.       do 115 i=1,m
  2335.       k=k+1
  2336.   115 b(k)=x(k)*xl(j)
  2337. c
  2338. c     form (b**(-1/2))prime * a * (b**(-1/2))
  2339. c
  2340.       do 120 i=1,m
  2341.       n2=0
  2342.       do 120 j=1,m
  2343.       n1=m*(i-1)
  2344.       l=m*(j-1)+i
  2345.       x(l)=0.0
  2346.       do 120 k=1,m
  2347.       n1=n1+1
  2348.       n2=n2+1
  2349.   120 x(l)=x(l)+b(n1)*a(n2)
  2350.       l=0
  2351.       do 130 j=1,m
  2352.       do 130 i=1,j
  2353.       n1=i-m
  2354.       n2=m*(j-1)
  2355.       l=l+1
  2356.       a(l)=0.0
  2357.       do 130 k=1,m
  2358.       n1=n1+m
  2359.       n2=n2+1
  2360.   130 a(l)=a(l)+x(n1)*b(n2)
  2361. c
  2362. c     compute eigenvalues and eigenvectors of a
  2363. c
  2364.       call eigen (a,x,m,mv)
  2365.       l=0
  2366.       do 140 i=1,m
  2367.       l=l+i
  2368.   140 xl(i)=a(l)
  2369. c
  2370. c     compute the normalized eigenvectors
  2371. c
  2372.       do 150 i=1,m
  2373.       n2=0
  2374.       do 150 j=1,m
  2375.       n1=i-m
  2376.       l=m*(j-1)+i
  2377.       a(l)=0.0
  2378.       do 150 k=1,m
  2379.       n1=n1+m
  2380.       n2=n2+1
  2381.   150 a(l)=a(l)+b(n1)*x(n2)
  2382. c
  2383. c     At this point, the routine differs from the standard ibm nroot.
  2384. c     The eigenvectors are not normalized to unit length. As a result,
  2385. c     instead of (x-prime)*(x)=i, we have (x-prime)*b*(x)=i , so that
  2386. c     the discriminant scores will have unit variances within-groups.
  2387.       n2 = m*m
  2388.       do 160 i=1,n2
  2389.   160 x(i)=a(i)
  2390.       return
  2391.       end
  2392.